Compare commits

...

135 Commits

Author SHA1 Message Date
Amir Raminfar
21e6b9e87c Release 3.6.1 2021-04-19 18:16:08 -07:00
Amir Raminfar
195f0da645 Fixes #1160 with nil pointer 2021-04-19 18:11:08 -07:00
Amir Raminfar
b18612942f Fixes shutdown signal 2021-04-19 15:06:22 -07:00
Amir Raminfar
ddb0c05173 Release 3.6.0 2021-04-19 13:26:49 -07:00
kodiakhq[bot]
590add10c1 Merge pull request #1159 from amir20/ga
Adds analytics for start flags
2021-04-19 19:39:54 +00:00
Amir Raminfar
984dbdf971 Updates docs and tests 2021-04-19 12:36:17 -07:00
Amir Raminfar
6c8828ffd7 Adds disable flag 2021-04-19 12:27:42 -07:00
Amir Raminfar
9fdfabfb5d Adds analytics for start params 2021-04-19 12:22:13 -07:00
dependabot[bot]
521b0bbbe8 Bump css-loader from 5.2.1 to 5.2.2 (#1157)
Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/webpack-contrib/css-loader/releases)
- [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/css-loader/compare/v5.2.1...v5.2.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-19 07:17:28 -07:00
kodiakhq[bot]
02f995f859 Merge pull request #1158 from amir20/dependabot/npm_and_yarn/integration/jest-puppeteer-5.0.1
Bump jest-puppeteer from 4.4.0 to 5.0.1 in /integration
2021-04-19 07:03:22 +00:00
dependabot[bot]
4c01314286 Bump jest-puppeteer from 4.4.0 to 5.0.1 in /integration
Bumps [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) from 4.4.0 to 5.0.1.
- [Release notes](https://github.com/smooth-code/jest-puppeteer/releases)
- [Changelog](https://github.com/smooth-code/jest-puppeteer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/smooth-code/jest-puppeteer/compare/v4.4.0...v5.0.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 06:59:15 +00:00
kodiakhq[bot]
e9231acc57 Merge pull request #1156 from amir20/dependabot/npm_and_yarn/sass-1.32.10
Bump sass from 1.32.8 to 1.32.10
2021-04-19 05:10:00 +00:00
kodiakhq[bot]
8977a71495 Merge pull request #1155 from amir20/dependabot/npm_and_yarn/caniuse-lite-1.0.30001210
Bump caniuse-lite from 1.0.30001208 to 1.0.30001210
2021-04-19 05:09:55 +00:00
kodiakhq[bot]
e6451cdcb6 Merge pull request #1154 from amir20/dependabot/npm_and_yarn/mini-css-extract-plugin-1.5.0
Bump mini-css-extract-plugin from 1.4.1 to 1.5.0
2021-04-19 05:08:59 +00:00
dependabot[bot]
f18e6d6adc Bump sass from 1.32.8 to 1.32.10
Bumps [sass](https://github.com/sass/dart-sass) from 1.32.8 to 1.32.10.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.32.8...1.32.10)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 05:06:18 +00:00
dependabot[bot]
7b05586a48 Bump caniuse-lite from 1.0.30001208 to 1.0.30001210
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001208 to 1.0.30001210.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001208...v1.0.30001210)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 05:05:49 +00:00
dependabot[bot]
9de4bc8a8c Bump mini-css-extract-plugin from 1.4.1 to 1.5.0
Bumps [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/webpack-contrib/mini-css-extract-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/mini-css-extract-plugin/compare/v1.4.1...v1.5.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-19 05:05:08 +00:00
Amir Raminfar
3defe22eed Creates a struct for event 2021-04-18 15:03:51 -07:00
Amir Raminfar
d65d899056 Adds more params 2021-04-18 14:39:21 -07:00
Amir Raminfar
b4f8b97b7d Fixes typo 2021-04-18 14:30:44 -07:00
Amir Raminfar
e3934e0422 Adds ga example 2021-04-18 14:14:53 -07:00
Amir Raminfar
a81415744a Fixes filter 2021-04-18 13:23:46 -07:00
Amir Raminfar
51a74691f9 Drops pflags and viper in favor of go-arg 2021-04-18 13:17:06 -07:00
kodiakhq[bot]
17d6d1b2ca Merge pull request #1153 from amir20/dependabot/npm_and_yarn/date-fns-2.21.1
Bump date-fns from 2.21.0 to 2.21.1
2021-04-16 05:08:13 +00:00
dependabot[bot]
ce755f61dc Bump date-fns from 2.21.0 to 2.21.1
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.21.0 to 2.21.1.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.21.0...v2.21.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-16 05:04:24 +00:00
kodiakhq[bot]
2e4665e468 Merge pull request #1152 from amir20/dependabot/npm_and_yarn/date-fns-2.21.0
Bump date-fns from 2.20.3 to 2.21.0
2021-04-15 05:09:23 +00:00
kodiakhq[bot]
72b89c5ea5 Merge pull request #1151 from amir20/dependabot/npm_and_yarn/webpack-5.33.2
Bump webpack from 5.32.0 to 5.33.2
2021-04-15 05:09:04 +00:00
dependabot[bot]
f77fac2221 Bump date-fns from 2.20.3 to 2.21.0
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.20.3 to 2.21.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.20.3...v2.21.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 05:05:43 +00:00
dependabot[bot]
9b347f3dfb Bump webpack from 5.32.0 to 5.33.2
Bumps [webpack](https://github.com/webpack/webpack) from 5.32.0 to 5.33.2.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.32.0...v5.33.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-15 05:04:35 +00:00
kodiakhq[bot]
c584c565a3 Merge pull request #1150 from amir20/dependabot/npm_and_yarn/date-fns-2.20.3
Bump date-fns from 2.20.2 to 2.20.3
2021-04-14 05:09:13 +00:00
dependabot[bot]
6730814ffc Bump date-fns from 2.20.2 to 2.20.3
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.20.2 to 2.20.3.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.20.2...v2.20.3)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-14 05:04:47 +00:00
Amir Raminfar
d57ea5233c Release 3.5.11 2021-04-13 18:51:27 -07:00
Amir Raminfar
90afa43cef Fixes TAG 2021-04-13 18:51:20 -07:00
Amir Raminfar
aac9905099 Release 3.5.10 2021-04-13 12:34:39 -07:00
Amir Raminfar
07723353d0 Adds labels 2021-04-13 12:25:06 -07:00
Amir Raminfar
c6a3b8f61e Release 3.5.9 2021-04-13 12:09:47 -07:00
Amir Raminfar
3db60e3d50 Adds QEMU 2021-04-13 12:09:40 -07:00
Amir Raminfar
b8d428f5b3 Release 3.5.8 2021-04-13 12:02:48 -07:00
Amir Raminfar
abca733e63 Removes context 2021-04-13 12:02:41 -07:00
Amir Raminfar
6bc133a643 Release 3.5.7 2021-04-13 11:55:36 -07:00
Amir Raminfar
280413c085 Uses local cache instead 2021-04-13 11:55:28 -07:00
Amir Raminfar
0bf265b001 Release 3.5.6 2021-04-13 11:48:29 -07:00
Amir Raminfar
c65d1f18ae Adds cache 2021-04-13 11:48:21 -07:00
Amir Raminfar
eb8f492ffe Release 3.5.5 2021-04-13 11:35:33 -07:00
Amir Raminfar
5358af5005 Adds setup buildx 2021-04-13 11:35:23 -07:00
Amir Raminfar
5569c7f5b4 Release 3.5.4 2021-04-13 11:29:48 -07:00
Amir Raminfar
5caf5eebb8 Uses docker/build-push-action (#1149) 2021-04-13 11:29:09 -07:00
kodiakhq[bot]
8ffe95b4ab Merge pull request #1148 from amir20/dependabot/go_modules/github.com/docker/docker-20.10.6incompatible
Bump github.com/docker/docker from 20.10.5+incompatible to 20.10.6+incompatible
2021-04-13 08:10:59 +00:00
dependabot[bot]
cca6b0971b Bump github.com/docker/docker
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 20.10.5+incompatible to 20.10.6+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Changelog](https://github.com/moby/moby/blob/master/CHANGELOG.md)
- [Commits](https://github.com/docker/docker/compare/v20.10.5...v20.10.6)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-13 08:06:09 +00:00
kodiakhq[bot]
0b45972692 Merge pull request #1147 from amir20/dependabot/npm_and_yarn/date-fns-2.20.2
Bump date-fns from 2.20.1 to 2.20.2
2021-04-13 05:09:40 +00:00
kodiakhq[bot]
84d626c75b Merge pull request #1146 from amir20/dependabot/npm_and_yarn/webpack-5.32.0
Bump webpack from 5.31.2 to 5.32.0
2021-04-13 05:08:31 +00:00
dependabot[bot]
380e65641e Bump date-fns from 2.20.1 to 2.20.2
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.20.1 to 2.20.2.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.20.1...v2.20.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-13 05:05:26 +00:00
dependabot[bot]
49a2bd918a Bump webpack from 5.31.2 to 5.32.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.31.2 to 5.32.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.31.2...v5.32.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-13 05:04:36 +00:00
Amir Raminfar
e35734d73a Adds more tests 2021-04-12 14:45:46 -07:00
kodiakhq[bot]
9103124bfa Merge pull request #1144 from amir20/dependabot/npm_and_yarn/vue/test-utils-1.1.4
Bump @vue/test-utils from 1.1.3 to 1.1.4
2021-04-12 05:09:24 +00:00
kodiakhq[bot]
c440aaf1a1 Merge pull request #1143 from amir20/dependabot/npm_and_yarn/postcss-8.2.10
Bump postcss from 8.2.9 to 8.2.10
2021-04-12 05:09:17 +00:00
kodiakhq[bot]
aaf3cd84f0 Merge pull request #1142 from amir20/dependabot/npm_and_yarn/release-it-14.6.1
Bump release-it from 14.6.0 to 14.6.1
2021-04-12 05:09:05 +00:00
dependabot[bot]
cc1e7d0cbe Bump @vue/test-utils from 1.1.3 to 1.1.4
Bumps [@vue/test-utils](https://github.com/vuejs/vue-test-utils/tree/HEAD/packages/test-utils) from 1.1.3 to 1.1.4.
- [Release notes](https://github.com/vuejs/vue-test-utils/releases)
- [Changelog](https://github.com/vuejs/vue-test-utils/blob/dev/packages/test-utils/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-test-utils/commits/v1.1.4/packages/test-utils)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-12 05:05:26 +00:00
dependabot[bot]
4012145a3e Bump postcss from 8.2.9 to 8.2.10
Bumps [postcss](https://github.com/postcss/postcss) from 8.2.9 to 8.2.10.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.2.9...8.2.10)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-12 05:05:03 +00:00
dependabot[bot]
b3cfec8402 Bump release-it from 14.6.0 to 14.6.1
Bumps [release-it](https://github.com/release-it/release-it) from 14.6.0 to 14.6.1.
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/14.6.0...14.6.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-12 05:04:39 +00:00
Amir Raminfar
3a555a8b04 Release 3.5.3 2021-04-11 14:57:21 -07:00
Amir Raminfar
99a023e3b1 Fixes int test snapshots 2021-04-11 14:52:46 -07:00
Amir Raminfar
f239d077a2 Adds more tests for auth 2021-04-11 14:46:59 -07:00
Amir Raminfar
f822bd5ccd Updates snapshot 2021-04-11 14:13:15 -07:00
Amir Raminfar
3c96572fb0 Fixes authrization bug 2021-04-11 14:12:37 -07:00
Amir Raminfar
4daccddab5 Adds more js tests 2021-04-11 14:02:56 -07:00
Amir Raminfar
41415e6731 Cleans up imports 2021-04-11 13:53:25 -07:00
Amir Raminfar
2bbbb5f7a5 Fixes security error with invalid session 2021-04-11 13:53:16 -07:00
Amir Raminfar
c89e70d697 Fixes #1137 by adding margin 0 2021-04-11 13:43:52 -07:00
kodiakhq[bot]
cbba0fa0ad Merge pull request #1138 from amir20/dependabot/npm_and_yarn/css-loader-5.2.1
Bump css-loader from 5.2.0 to 5.2.1
2021-04-11 20:35:24 +00:00
kodiakhq[bot]
a60634ab1b Merge pull request #1139 from amir20/dependabot/npm_and_yarn/release-it-14.6.0
Bump release-it from 14.5.1 to 14.6.0
2021-04-11 20:35:15 +00:00
kodiakhq[bot]
0a9072cf53 Merge pull request #1140 from amir20/dependabot/npm_and_yarn/date-fns-2.20.1
Bump date-fns from 2.20.0 to 2.20.1
2021-04-11 20:35:04 +00:00
kodiakhq[bot]
dfaea1c95a Merge pull request #1141 from amir20/dependabot/npm_and_yarn/webpack-5.31.2
Bump webpack from 5.31.0 to 5.31.2
2021-04-11 20:34:54 +00:00
Amir Raminfar
a331b6a20b Configures kodiak 2021-04-11 13:34:39 -07:00
Amir Raminfar
3d710118e1 Merge branch 'master' into dependabot/npm_and_yarn/css-loader-5.2.1 2021-04-10 21:18:18 -07:00
Amir Raminfar
be24567d74 Merge branch 'master' into dependabot/npm_and_yarn/release-it-14.6.0 2021-04-10 21:18:10 -07:00
Amir Raminfar
cf7594af38 Merge branch 'master' into dependabot/npm_and_yarn/date-fns-2.20.1 2021-04-10 21:18:03 -07:00
Amir Raminfar
0527d58959 Merge branch 'master' into dependabot/npm_and_yarn/webpack-5.31.2 2021-04-10 21:17:51 -07:00
dependabot[bot]
36984d0787 Bump webpack from 5.31.0 to 5.31.2
Bumps [webpack](https://github.com/webpack/webpack) from 5.31.0 to 5.31.2.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.31.0...v5.31.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 00:32:21 +00:00
dependabot[bot]
f6ec3126a4 Bump date-fns from 2.20.0 to 2.20.1
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.20.0 to 2.20.1.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.20.0...v2.20.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 00:32:01 +00:00
dependabot[bot]
767fc4fde3 Bump release-it from 14.5.1 to 14.6.0
Bumps [release-it](https://github.com/release-it/release-it) from 14.5.1 to 14.6.0.
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/14.5.1...14.6.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 00:31:48 +00:00
dependabot[bot]
137dc490ce Bump css-loader from 5.2.0 to 5.2.1
Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/webpack-contrib/css-loader/releases)
- [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/css-loader/compare/v5.2.0...v5.2.1)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-11 00:31:36 +00:00
Amir Raminfar
4d7a682ecf Release 3.5.2 2021-04-10 17:29:59 -07:00
Amir Raminfar
7b4ca4e4fa Fixes tests for hourstyle 2021-04-10 17:14:28 -07:00
Amir Raminfar
232ec7d27a Adds seconds and fixes #1136 2021-04-10 17:07:30 -07:00
Amir Raminfar
bba34aa582 Minor clean up 2021-04-10 17:03:34 -07:00
github-actions[bot]
70a40cd7e4 Merge pull request #1133 from amir20/dependabot/npm_and_yarn/babel/plugin-transform-runtime-7.13.15 2021-04-09 21:42:28 +00:00
dependabot[bot]
b90f79449b Bump @babel/plugin-transform-runtime from 7.13.10 to 7.13.15
Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.13.10 to 7.13.15.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.15/packages/babel-plugin-transform-runtime)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-09 21:34:34 +00:00
Amir Raminfar
8aea96d336 Release 3.5.1 2021-04-09 14:29:50 -07:00
Amir Raminfar
ed80bff954 Set maximum buffer size fixes #1135 2021-04-09 14:24:42 -07:00
github-actions[bot]
013aefa969 Merge pull request #1132 from amir20/dependabot/npm_and_yarn/babel/core-7.13.15 2021-04-09 17:09:57 +00:00
dependabot[bot]
986fe38254 Bump @babel/core from 7.13.14 to 7.13.15
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.13.14 to 7.13.15.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.13.15/packages/babel-core)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-09 17:05:29 +00:00
dependabot[bot]
9c9172a180 Bump caniuse-lite from 1.0.30001207 to 1.0.30001208 (#1134)
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001207 to 1.0.30001208.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001207...v1.0.30001208)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-09 10:00:41 -07:00
Amir Raminfar
7f9fd2c80c Release 3.5.0 2021-04-08 16:32:40 -07:00
Amir Raminfar
c8202d1238 Fixes z-index bug #1091 2021-04-08 16:32:13 -07:00
Amir Raminfar
91b02bcfce Updates .reflex config 2021-04-08 16:17:54 -07:00
Amir Raminfar
46c4dde573 Adds auto focus to username 2021-04-08 16:14:50 -07:00
Amir Raminfar
52729fa980 Fixes mobile, colors and removes heading 2021-04-08 14:36:43 -07:00
dependabot[bot]
915cff92c6 Bump mini-css-extract-plugin from 1.4.0 to 1.4.1 (#1129)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-08 14:19:31 -07:00
dependabot[bot]
b591595285 Bump date-fns from 2.19.0 to 2.20.0 (#1130)
Bumps [date-fns](https://github.com/date-fns/date-fns) from 2.19.0 to 2.20.0.
- [Release notes](https://github.com/date-fns/date-fns/releases)
- [Changelog](https://github.com/date-fns/date-fns/blob/master/CHANGELOG.md)
- [Commits](https://github.com/date-fns/date-fns/compare/v2.19.0...v2.20.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-08 14:19:16 -07:00
dependabot[bot]
0486db9169 Bump buefy from 0.9.5 to 0.9.6 (#1131)
Bumps [buefy](https://github.com/buefy/buefy) from 0.9.5 to 0.9.6.
- [Release notes](https://github.com/buefy/buefy/releases)
- [Changelog](https://github.com/buefy/buefy/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/buefy/buefy/compare/v0.9.5...v0.9.6)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-04-08 14:19:05 -07:00
Amir Raminfar
4a1c699e93 Adds a new test 2021-04-08 10:22:34 -07:00
Amir Raminfar
83e4175fca Cleans up tests 2021-04-08 10:19:02 -07:00
Amir Raminfar
b8bec9d2f0 Updates makefile 2021-04-08 08:35:36 -07:00
Amir Raminfar
802744d132 Fixes relfex 2021-04-08 08:31:25 -07:00
Amir Raminfar
b4e0afdb2c Adds authentication as a feature with simple username and password configuration (#1127)
* Starting work for auth

* Adds flags

* Does redirect

* Refactors code

* Adds vue templates

* Completes logic

* Cleans up some of the error messages

* Refactors

* Updates readme

* Updates titles

* Adds logout

* Cleans up imports
2021-04-08 08:29:58 -07:00
github-actions[bot]
7b7fd11bc7 Merge pull request #1128 from amir20/dependabot/npm_and_yarn/webpack-5.31.0 2021-04-08 14:44:59 +00:00
dependabot[bot]
b8beb4eba7 Bump webpack from 5.30.0 to 5.31.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.30.0 to 5.31.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.30.0...v5.31.0)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-08 14:34:22 +00:00
Amir Raminfar
e3e28e7e3d Delete codeql-analysis.yml 2021-04-08 07:29:47 -07:00
github-actions[bot]
509de3b89c Merge pull request #1125 from amir20/dependabot/github_actions/actions/setup-node-v2.1.5 2021-04-06 02:07:18 +00:00
github-actions[bot]
f3aef59740 Merge pull request #1126 from amir20/dependabot/github_actions/actions/setup-go-v2.1.3 2021-04-06 02:07:03 +00:00
dependabot[bot]
27d351f21c Bump actions/setup-go from v1 to v2.1.3
Bumps [actions/setup-go](https://github.com/actions/setup-go) from v1 to v2.1.3.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/v1...37335c7bb261b353407cff977110895fa0b4f7d8)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-06 02:04:48 +00:00
dependabot[bot]
e98b482b73 Bump actions/setup-node from v1 to v2.1.5
Bumps [actions/setup-node](https://github.com/actions/setup-node) from v1 to v2.1.5.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v1...46071b5c7a2e0c34e49c3cb8a0e792e86e18d5ea)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-06 02:04:45 +00:00
Amir Raminfar
70a4dc5734 Updates depndabot 2021-04-05 19:04:24 -07:00
github-actions[bot]
cda7318e45 Merge pull request #1124 from amir20/dependabot/go_modules/github.com/magiconair/properties-1.8.5 2021-04-05 19:02:49 +00:00
Amir Raminfar
6b098e1233 Adds automerge 2021-04-05 11:56:17 -07:00
dependabot[bot]
a6f28488ee Bump github.com/magiconair/properties from 1.8.4 to 1.8.5
Bumps [github.com/magiconair/properties](https://github.com/magiconair/properties) from 1.8.4 to 1.8.5.
- [Release notes](https://github.com/magiconair/properties/releases)
- [Changelog](https://github.com/magiconair/properties/blob/main/CHANGELOG.md)
- [Commits](https://github.com/magiconair/properties/compare/v1.8.4...v1.8.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-05 18:53:17 +00:00
Amir Raminfar
f4091ba95c Adds labels 2021-04-05 11:50:49 -07:00
dependabot-preview[bot]
d597f4d3f7 Create Dependabot config file (#1123)
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
2021-04-05 11:49:31 -07:00
dependabot-preview[bot]
f9bbf7081f Merge pull request #1122 from amir20/dependabot/npm_and_yarn/caniuse-lite-1.0.30001207 2021-04-05 05:49:31 +00:00
dependabot-preview[bot]
42f2028c29 Bump caniuse-lite from 1.0.30001205 to 1.0.30001207
Bumps [caniuse-lite](https://github.com/ben-eb/caniuse-lite) from 1.0.30001205 to 1.0.30001207.
- [Release notes](https://github.com/ben-eb/caniuse-lite/releases)
- [Changelog](https://github.com/ben-eb/caniuse-lite/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ben-eb/caniuse-lite/compare/v1.0.30001205...v1.0.30001207)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-05 05:44:30 +00:00
dependabot-preview[bot]
0b09d6c785 Merge pull request #1120 from amir20/dependabot/npm_and_yarn/integration/jest-image-snapshot-4.4.1 2021-04-02 13:23:26 +00:00
dependabot-preview[bot]
33430b2974 Merge pull request #1119 from amir20/dependabot/npm_and_yarn/release-it-14.5.1 2021-04-02 13:20:09 +00:00
dependabot-preview[bot]
ac64579bcd Bump jest-image-snapshot from 4.4.0 to 4.4.1 in /integration
Bumps [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot) from 4.4.0 to 4.4.1.
- [Release notes](https://github.com/americanexpress/jest-image-snapshot/releases)
- [Changelog](https://github.com/americanexpress/jest-image-snapshot/blob/master/CHANGELOG.md)
- [Commits](https://github.com/americanexpress/jest-image-snapshot/compare/v4.4.0...v4.4.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-02 13:18:49 +00:00
dependabot-preview[bot]
dd7929ec59 Bump release-it from 14.5.0 to 14.5.1
Bumps [release-it](https://github.com/release-it/release-it) from 14.5.0 to 14.5.1.
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/master/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/14.5.0...14.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-02 13:14:33 +00:00
Amir Raminfar
17fe73bd27 Updates readme 2021-04-01 19:40:42 -07:00
Amir Raminfar
a607c2d021 Release 3.4.8 2021-04-01 19:05:10 -07:00
Amir Raminfar
a840f19b20 Missed a font 2021-04-01 19:05:00 -07:00
Amir Raminfar
ec4f3c0339 Release 3.4.7 2021-04-01 13:03:02 -07:00
Amir Raminfar
721e30385e Fixes release and updates fonts again 2021-04-01 13:02:41 -07:00
Amir Raminfar
ee95bc75fb Add changelog 2021-04-01 12:49:16 -07:00
Amir Raminfar
6ec6d26f52 Release 3.4.6 2021-04-01 12:28:14 -07:00
Amir Raminfar
c53b21d0af Fixes CI bug 2021-04-01 12:25:05 -07:00
dependabot-preview[bot]
d03d278bb9 Merge pull request #1118 from amir20/dependabot/npm_and_yarn/webpack-5.30.0 2021-04-01 18:57:09 +00:00
dependabot-preview[bot]
84bdc26547 Bump webpack from 5.28.0 to 5.30.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.28.0 to 5.30.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.28.0...v5.30.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-01 18:51:09 +00:00
50 changed files with 1452 additions and 1066 deletions

40
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
labels:
- "dependencies"
- "automerge"
schedule:
interval: "daily"
- package-ecosystem: "docker"
directory: "/"
labels:
- "dependencies"
- "automerge"
schedule:
interval: "daily"
- package-ecosystem: gomod
directory: "/"
labels:
- "gomod"
- "dependencies"
- "automerge"
schedule:
interval: daily
- package-ecosystem: npm
directory: "/"
labels:
- "npm"
- "dependencies"
- "automerge"
schedule:
interval: daily
- package-ecosystem: npm
directory: "/integration"
labels:
- "npm"
- "dependencies"
- "automerge"
schedule:
interval: daily

View File

@@ -1,67 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '42 21 * * 0'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'go', 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View File

@@ -11,7 +11,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node
uses: actions/setup-node@v1
uses: actions/setup-node@v2.1.5
- name: Install dependencies
run: yarn
- name: Run Tests
@@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v1
uses: actions/setup-go@v2.1.3
with:
go-version: 1.16.x
- name: Checkout code
@@ -43,19 +43,44 @@ jobs:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Docker meta
id: meta
uses: crazy-max/ghaction-docker-meta@v2
with:
images: amir20/dozzle
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
- name: Available platforms
run: echo ${{ steps.buildx.outputs.platforms }}
- name: Docker Login
run: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
- name: Run Buildx
run: make publish
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Cache Docker layers
uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Build and push
uses: docker/build-push-action@v2
with:
push: true
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
tags: ${{ steps.meta.outputs.tags }}
build-args: TAG=${{ steps.meta.outputs.version }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- # Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
git-release:
needs: [buildx]
name: Github Release
@@ -63,11 +88,13 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install Node
uses: actions/setup-node@v1
uses: actions/setup-node@v2.1.5
- name: Install dependencies
run: yarn
- name: Release to Github
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: yarn release --github.release --no-increment --no-git
run: yarn release --github.release --no-increment --no-git --ci

View File

@@ -8,7 +8,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v2
- name: Install Node
uses: actions/setup-node@v1
uses: actions/setup-node@v2.1.5
- name: Install dependencies
run: yarn
- name: Run Tests
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install Go
uses: actions/setup-go@v1
uses: actions/setup-go@v2.1.3
with:
go-version: 1.16.x
- name: Checkout code

1
.kodiak.toml Normal file
View File

@@ -0,0 +1 @@
version = 1

View File

@@ -1 +1 @@
-r '\.go$' -R 'node_modules' -R '^static/' -R '^.cache/' -G '*_test.go' -s -- go run main.go --level debug
-r '\.(go)$' -R 'node_modules' -G '*_test.go' -s -- go run main.go --level debug

View File

@@ -1,11 +1,3 @@
TAG := $(shell git describe --tags)
PLATFROMS := linux/amd64,linux/arm/v7,linux/arm64/v8
.PHONY: publish
publish:
docker buildx build --build-arg TAG=$(TAG) --platform $(PLATFROMS) -t amir20/dozzle:latest -t amir20/dozzle:$(TAG) --push .
.PHONY: clean
clean:
@rm -rf static
@@ -25,8 +17,18 @@ fake_static:
test: fake_static
go test -cover ./...
.PHONY: build
build: static
CGO_ENABLED=0 go build -ldflags "-s -w"
.PHONY: docker
docker:
@docker build -t amir20/dozzle .
.PHONY: dev
dev:
yarn dev
.PHONY: int
int:
docker-compose -f integration/docker-compose.test.yml up --build --force-recreate --exit-code-from integration

View File

@@ -1,32 +1,42 @@
# Dozzle - [dozzle.dev](https://dozzle.dev/)
Dozzle is a simple, lightweight application that provides you with a web based interface to monitor your Docker container logs live. It doesnt store log information, it is for live monitoring of your container logs only.
![Image](https://github.com/amir20/dozzle/blob/master/.github/demo.gif?raw=true)
[![Go Report Card](https://goreportcard.com/badge/github.com/amir20/dozzle)](https://goreportcard.com/report/github.com/amir20/dozzle)
[![Docker Pulls](https://img.shields.io/docker/pulls/amir20/dozzle.svg)](https://hub.docker.com/r/amir20/dozzle/)
[![Docker Size](https://images.microbadger.com/badges/image/amir20/dozzle.svg)](https://hub.docker.com/r/amir20/dozzle/)
[![Docker Version](https://images.microbadger.com/badges/version/amir20/dozzle.svg)](https://hub.docker.com/r/amir20/dozzle/)
![Test](https://github.com/amir20/dozzle/workflows/Test/badge.svg)
# Dozzle - [dozzle.dev](https://dozzle.dev/)
## Features
Dozzle is a simple, lightweight application that provides you with a web based interface to monitor your Docker container logs live. It doesnt store log information, it is for live monitoring of your container logs only.
- Intelligent fuzzy search for container names 🤖
- Search logs using regex 🔦
- Small memory footprint 🏎
- Split screen for viewing multiple logs
- Download logs easy
- Live stats with memory and CPU usage
- Authentication with username and password 🚨
While dozzle should work for most, it is not meant to be a full logging solution. For enterprise applications, products like [Loggly](https://www.loggly.com), [Papertrail](https://papertrailapp.com) or [Kibana](https://www.elastic.co/products/kibana) are more suited.
While Dozzle should work for most, it is not meant to be a full logging solution. For enterprise applications, products like [Loggly](https://www.loggly.com), [Papertrail](https://papertrailapp.com) or [Kibana](https://www.elastic.co/products/kibana) are more suited.
Dozzle doesn't cost any money. Dozzle aims to stay simple, small and free.
Dozzle won't cost any money and aims to focus only on real-time logs.
![Image](https://github.com/amir20/dozzle/blob/master/.github/demo.gif?raw=true)
## Getting dozzle
## Getting Dozzle
Dozzle is a very small Docker container (4 MB compressed). Pull the latest release from the index:
$ docker pull amir20/dozzle:latest
## Using dozzle
## Using Dozzle
The simplest way to use dozzle is to run the docker container. Also, mount the Docker Unix socket with `--volume` to `/var/run/docker.sock`:
$ docker run --name dozzle -d --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:8080 amir20/dozzle:latest
dozzle will be available at [http://localhost:8888/](http://localhost:8888/). You can change `-p 8888:8080` to any port. For example, if you want to view dozzle over port 4040 then you would do `-p 4040:8080`.
Dozzle will be available at [http://localhost:8888/](http://localhost:8888/). You can change `-p 8888:8080` to any port. For example, if you want to view dozzle over port 4040 then you would do `-p 4040:8080`.
### With Docker swarm
@@ -51,7 +61,7 @@ dozzle will be available at [http://localhost:8888/](http://localhost:8888/). Yo
#### Security
dozzle doesn't support authentication out of the box. You can control the device dozzle binds to by passing `--addr` parameter. For example,
You can control the device Dozzle binds to by passing `--addr` parameter. For example,
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8888:1224 amir20/dozzle:latest --addr localhost:1224
@@ -63,36 +73,50 @@ If you wish to restrict the containers shown you can pass the `--filter` paramet
this would then only allow you to view containers with a name starting with "foo". You can use other filters like `status` as well, please check the official docker [command line docs](https://docs.docker.com/engine/reference/commandline/ps/#filtering) for available filters.
Dozzle supports very simple authentication out of the box with username and password. You should deploy using SSL to keep the credentials safe.
#### Changing base URL
dozzle by default mounts to "/". If you want to control the base path you can use the `--base` option. For example, if you want to mount at "/foobar",
Dozzle by default mounts to "/". If you want to control the base path you can use the `--base` option. For example, if you want to mount at "/foobar",
then you can override by using `--base /foobar`. See env variables below for using `DOZZLE_BASE` to change this.
$ docker run --volume=/var/run/docker.sock:/var/run/docker.sock -p 8080:8080 amir20/dozzle:latest --base /foobar
dozzle will be available at [http://localhost:8080/foobar/](http://localhost:8080/foobar/).
Dozzle will be available at [http://localhost:8080/foobar/](http://localhost:8080/foobar/).
#### Analytics collected
Dozzle collects anonymous user configurations using Google Analytics. Why? Dozzle is an open source project with no funding. As a result, there is not time do user studies of Dozzle. Analytics is collected to prioritize features and fixes based on how people use Dozzle.
If you do not want to be tracked at all, see the `--no-analytics` flag below.
#### Environment variables and configuration
Dozzle follows the [12-factor](https://12factor.net/) model. Configurations can use the CLI flags or enviroment variables. The table below outlines all supported options and their respective env vars.
Dozzle follows the [12-factor](https://12factor.net/) model. Configurations can use the CLI flags or environment variables. The table below outlines all supported options and their respective env vars.
| Flag | Env Variable | Default |
| ------------ | -------------------- | ------- |
| `--addr` | `DOZZLE_ADDR` | `:8080` |
| `--base` | `DOZZLE_BASE` | `/` |
| `--level` | `DOZZLE_LEVEL` | `info` |
| n/a | `DOCKER_API_VERSION` | not set |
| `--tailSize` | `DOZZLE_TAILSIZE` | `300` |
| `--filter` | `DOZZLE_FILTER` | `""` |
| Flag | Env Variable | Default |
| ---------------- | --------------------- | ------- |
| `--addr` | `DOZZLE_ADDR` | `:8080` |
| `--base` | `DOZZLE_BASE` | `/` |
| `--level` | `DOZZLE_LEVEL` | `info` |
| n/a | `DOCKER_API_VERSION` | not set |
| `--tailSize` | `DOZZLE_TAILSIZE` | `300` |
| `--filter` | `DOZZLE_FILTER` | `""` |
| `--username` | `DOZZLE_USERNAME` | `""` |
| `--password` | `DOZZLE_PASSWORD` | `""` |
| `--key` | `DOZZLE_KEY` | `""` |
| `--no-analytics` | `DOZZLE_NO_ANALYTICS` | false |
Note: When using username and password `DOZZLE_KEY` is required for session management.
## Troubleshooting and FAQs
<details>
<summary>I installed Dozzle, but logs are slow or they never load. Help!</summary>
Dozzle uses Server Sent Events (SSE) which connects to a server using a HTTP stream without closing the connection. If any proxy tries to buffer this connection, then Dozzle never receives the data and hangs forever waiting for the reverse proxy to flush the buffer. Since version `1.23.0`, Dozzle sends the `X-Accel-Buffering: no` header which should stop reverse proxies buffering. However, some proxies may ignore this header. In those cases, you need to explicitly disable any buffering.
Dozzle uses Server Sent Events (SSE) which connects to a server using a HTTP stream without closing the connection. If any proxy tries to buffer this connection, then Dozzle never receives the data and hangs forever waiting for the reverse proxy to flush the buffer. Since version `1.23.0`, Dozzle sends the `X-Accel-Buffering: no` header which should stop reverse proxies buffering. However, some proxies may ignore this header. In those cases, you need to explicitly disable any buffering.
Below is an example with nginx and using `proxy_pass` to disable buffering.
Below is an example with nginx and using `proxy_pass` to disable buffering.
```
server {
@@ -111,20 +135,21 @@ Dozzle follows the [12-factor](https://12factor.net/) model. Configurations can
}
```
</details>
<details>
<summary>What data does Dozzle collect?</summary>
Dozzle does not collect any metrics or analytics. Dozzle has a [strict](https://github.com/amir20/dozzle/blob/master/routes.go#L33-L38) Content Security Policy which only allows the following policies:
Dozzle does not collect any metrics or analytics. Dozzle has a [strict](https://github.com/amir20/dozzle/blob/master/routes.go#L33-L38) Content Security Policy which only allows the following policies:
- Allow connect to `api.github.com` to fetch most recent version.
- Only allow `<script>` and `<style>` files from `self`
- Allow connect to `api.github.com` to fetch most recent version.
- Only allow `<script>` and `<style>` files from `self`
Dozzle opens all links with `rel="noopener"`.
Dozzle opens all links with `rel="noopener"`.
</details>
## License
[MIT](LICENSE)

55
analytics/ga.go Normal file
View File

@@ -0,0 +1,55 @@
package analytics
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/http/httputil"
log "github.com/sirupsen/logrus"
)
func SendStartEvent(se StartEvent) error {
postBody := map[string]interface{}{
"client_id": se.ClientId,
"events": []map[string]interface{}{
{
"name": "start",
"params": se,
},
},
}
jsonValue, err := json.Marshal(postBody)
if err != nil {
return err
}
req, err := http.NewRequest("POST", "https://www.google-analytics.com/mp/collect", bytes.NewBuffer(jsonValue))
if err != nil {
return err
}
q := req.URL.Query()
q.Add("measurement_id", "G-S6NT05VXK9")
q.Add("api_secret", "7FFhe65HQK-bXvujpQMquQ")
req.URL.RawQuery = q.Encode()
response, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode/100 != 2 {
dump, err := httputil.DumpResponse(response, true)
if err != nil {
return err
}
log.Debugf("%v", string(dump))
return fmt.Errorf("google analytics returned non-2xx status code: %v", response.Status)
}
return nil
}

11
analytics/types.go Normal file
View File

@@ -0,0 +1,11 @@
package analytics
type StartEvent struct {
ClientId string `json:"-"`
Version string `json:"version"`
FilterLength int `json:"filterLength"`
CustomAddress bool `json:"customAddress"`
CustomBase bool `json:"customBase"`
TailSize int `json:"tailSize"`
Protected bool `json:"protected"`
}

View File

@@ -1,9 +1,9 @@
<template>
<main>
<mobile-menu v-if="isMobile"></mobile-menu>
<mobile-menu v-if="isMobile && !authorizationNeeded"></mobile-menu>
<splitpanes @resized="onResized($event)">
<pane min-size="10" :size="settings.menuWidth" v-if="!isMobile && !collapseNav">
<pane min-size="10" :size="settings.menuWidth" v-if="!authorizationNeeded && !isMobile && !collapseNav">
<side-menu @search="showFuzzySearch"></side-menu>
</pane>
<pane min-size="10">
@@ -11,15 +11,17 @@
<pane class="has-min-height router-view">
<router-view></router-view>
</pane>
<pane v-for="other in activeContainers" :key="other.id" v-if="!isMobile">
<log-container
:id="other.id"
show-title
scrollable
closable
@close="removeActiveContainer(other)"
></log-container>
</pane>
<template v-if="!isMobile">
<pane v-for="other in activeContainers" :key="other.id">
<log-container
:id="other.id"
show-title
scrollable
closable
@close="removeActiveContainer(other)"
></log-container>
</pane>
</template>
</splitpanes>
</pane>
</splitpanes>
@@ -28,7 +30,7 @@
class="button is-small is-rounded is-settings-control"
:class="{ collapsed: collapseNav }"
id="hide-nav"
v-if="!isMobile"
v-if="!isMobile && !authorizationNeeded"
>
<span class="icon">
<icon :name="collapseNav ? 'chevron-right' : 'chevron-left'"></icon>
@@ -106,7 +108,7 @@ export default {
},
},
computed: {
...mapState(["isMobile", "settings", "containers"]),
...mapState(["isMobile", "settings", "containers", "authorizationNeeded"]),
...mapGetters(["visibleContainers", "activeContainers"]),
hasSmallerScrollbars() {
return this.settings.smallerScrollbars;

View File

@@ -27,13 +27,13 @@ describe("<LogEventSource />", () => {
debounce.mockClear();
});
function createLogEventSource(searchFilter = null) {
function createLogEventSource({ hourStyle = "auto", searchFilter = null } = {}) {
const localVue = createLocalVue();
localVue.use(Vuex);
localVue.component("log-viewer", LogViewer);
const state = { searchFilter, settings: { size: "medium", showTimestamp: true } };
const state = { searchFilter, settings: { size: "medium", showTimestamp: true, hourStyle } };
const store = new Vuex.Store({
state,
@@ -144,7 +144,7 @@ describe("<LogEventSource />", () => {
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55 AM</time></span> <span class="text"> "This is a message."</span></li>
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55:42 AM</time></span> <span class="text"> "This is a message."</span></li>
</ul>
`);
});
@@ -159,7 +159,7 @@ describe("<LogEventSource />", () => {
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55 AM</time></span> <span class="text"> <span style="color:#000">black<span style="color:#AAA">white</span></span></span></li>
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55:42 AM</time></span> <span class="text"> <span style="color:#000">black<span style="color:#AAA">white</span></span></span></li>
</ul>
`);
});
@@ -174,13 +174,43 @@ describe("<LogEventSource />", () => {
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55 AM</time></span> <span class="text"> &lt;test&gt;foo bar&lt;/test&gt;</span></li>
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55:42 AM</time></span> <span class="text"> &lt;test&gt;foo bar&lt;/test&gt;</span></li>
</ul>
`);
});
test("should render dates with 12 hour style", async () => {
const wrapper = createLogEventSource({ hourStyle: "12" });
sources["/api/logs/stream?id=abc"].emitOpen();
sources["/api/logs/stream?id=abc"].emitMessage({
data: `2019-06-12T23:55:42.459034602Z <test>foo bar</test>`,
});
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T23:55:42.459Z">today at 11:55:42 PM</time></span> <span class="text"> &lt;test&gt;foo bar&lt;/test&gt;</span></li>
</ul>
`);
});
test("should render dates with 24 hour style", async () => {
const wrapper = createLogEventSource({ hourStyle: "24" });
sources["/api/logs/stream?id=abc"].emitOpen();
sources["/api/logs/stream?id=abc"].emitMessage({
data: `2019-06-12T23:55:42.459034602Z <test>foo bar</test>`,
});
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T23:55:42.459Z">today at 23:55:42</time></span> <span class="text"> &lt;test&gt;foo bar&lt;/test&gt;</span></li>
</ul>
`);
});
test("should render messages with filter", async () => {
const wrapper = createLogEventSource("test");
const wrapper = createLogEventSource({ searchFilter: "test" });
sources["/api/logs/stream?id=abc"].emitOpen();
sources["/api/logs/stream?id=abc"].emitMessage({
data: `2019-06-11T10:55:42.459034602Z Foo bar`,
@@ -192,7 +222,7 @@ describe("<LogEventSource />", () => {
await wrapper.vm.$nextTick();
expect(wrapper.find("ul.events")).toMatchInlineSnapshot(`
<ul class="events medium">
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55 AM</time></span> <span class="text"> This is a <mark>test</mark> &lt;hi&gt;&lt;/hi&gt;</span></li>
<li class=""><span class="date"><time datetime="2019-06-12T10:55:42.459Z">today at 10:55:42 AM</time></span> <span class="text"> This is a <mark>test</mark> &lt;hi&gt;&lt;/hi&gt;</span></li>
</ul>
`);
});

View File

@@ -30,7 +30,7 @@ export default {
methods: {
loadLogs(id) {
this.reset();
this.es = new EventSource(`${config.base}/api/logs/stream?id=${this.id}`);
this.es = new EventSource(`${config.base}/api/logs/stream?id=${id}`);
this.es.addEventListener("container-stopped", (e) => {
this.es.close();
this.buffer.push({ event: "container-stopped", message: "Container stopped", date: new Date() });

View File

@@ -7,7 +7,7 @@
</ul>
</template>
<script>
import { mapActions, mapGetters, mapState } from "vuex";
import { mapState } from "vuex";
import AnsiConvertor from "ansi-to-html";
import DOMPurify from "dompurify";
import RelativeTime from "./RelativeTime";
@@ -63,8 +63,8 @@ export default {
</script>
<style scoped lang="scss">
.events {
padding: 10px;
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monaco, monospace;
padding: 1em;
font-family: SFMono-Regular, Consolas, Liberation Mono, monaco, Menlo, monospace;
& > li {
word-wrap: break-word;

View File

@@ -70,7 +70,7 @@ aside {
left: 0;
right: 0;
background: var(--scheme-main-ter);
z-index: 2;
z-index: 10;
max-height: 100vh;
overflow: auto;

View File

@@ -3,9 +3,10 @@
</template>
<script>
import { mapActions, mapState } from "vuex";
import { mapState } from "vuex";
import { formatRelative } from "date-fns";
import { enGB, enUS } from "date-fns/locale";
import enGB from "date-fns/locale/en-GB";
import enUS from "date-fns/locale/en-US";
const use24Hr =
new Intl.DateTimeFormat(undefined, {
@@ -30,7 +31,14 @@ export default {
computed: {
...mapState(["settings"]),
locale() {
return styles[this.settings.hourStyle];
const locale = styles[this.settings.hourStyle];
const oldFormatter = locale.formatRelative;
return {
...locale,
formatRelative(token) {
return oldFormatter(token) + "p";
},
};
},
},
filters: {

View File

@@ -7,7 +7,9 @@
<script type="application/json" id="config__json">
{
"base": "{{ .Base }}",
"version": "{{ .Version }}"
"version": "{{ .Version }}",
"authorizationNeeded": "{{ .AuthorizationNeeded }}",
"secured": "{{ .Secured }}"
}
</script>
</head>

View File

@@ -10,7 +10,7 @@ import Autocomplete from "buefy/dist/esm/autocomplete";
import store from "./store";
import config from "./store/config";
import App from "./App.vue";
import { Container, Settings, Index, Show, ContainerNotFound, PageNotFound } from "./pages";
import { Container, Settings, Index, Show, ContainerNotFound, PageNotFound, Login } from "./pages";
Vue.use(VueRouter);
Vue.use(Meta);
@@ -47,6 +47,11 @@ const routes = [
component: Show,
name: "show",
},
{
path: "/login",
component: Login,
name: "login",
},
{
path: "/*",
component: PageNotFound,

View File

@@ -6,7 +6,7 @@
</template>
<script>
import { mapActions, mapGetters, mapState } from "vuex";
import { mapGetters } from "vuex";
import Search from "../components/Search";
import LogContainer from "../components/LogContainer";

View File

@@ -14,5 +14,10 @@
<script>
export default {
name: "ContainerNotFound",
metaInfo() {
return {
title: "Not Found",
};
},
};
</script>

View File

@@ -3,7 +3,14 @@
<section class="hero is-small mt-4">
<div class="hero-body">
<div class="container">
<h1 class="title">Hello, there!</h1>
<div class="columns">
<div class="column">
<h1 class="title">Hello, there!</h1>
</div>
<div class="column is-narrow" v-if="secured">
<a class="button is-primary is-small" :href="`${base}/logout`">Logout</a>
</div>
</div>
</div>
</div>
</section>
@@ -28,7 +35,7 @@
</div>
</section>
<section class="columns is-centered section">
<section class="columns is-centered section is-marginless">
<div class="column is-4">
<div class="panel">
<p class="panel-heading">Containers</p>
@@ -84,6 +91,8 @@ export default {
version: config.version,
search: null,
sort: "running",
secured: config.secured,
base: config.base,
};
},
methods: {

84
assets/pages/Login.vue Normal file
View File

@@ -0,0 +1,84 @@
<template>
<div class="hero is-halfheight">
<div class="hero-body">
<div class="container">
<section class="columns is-centered section">
<div class="column is-4">
<div class="card">
<div class="card-content">
<form action="" method="post" @submit.prevent="onLogin" ref="form">
<div class="field">
<label class="label">Username</label>
<div class="control">
<input
class="input"
type="text"
name="username"
autocomplete="username"
v-model="username"
autofocus
/>
</div>
</div>
<div class="field">
<label class="label">Password</label>
<div class="control">
<input
class="input"
type="password"
name="password"
autocomplete="current-password"
v-model="password"
/>
</div>
<p class="help is-danger" v-if="error">Username and password are not valid.</p>
</div>
<div class="field is-grouped is-grouped-centered mt-5">
<p class="control">
<button class="button is-primary" type="submit">Login</button>
</p>
</div>
</form>
</div>
</div>
</div>
</section>
</div>
</div>
</div>
</template>
<script>
import config from "../store/config";
export default {
name: "Login",
data() {
return {
username: null,
password: null,
error: false,
};
},
metaInfo() {
return {
title: "Authentication Required",
};
},
methods: {
async onLogin() {
const response = await fetch(`${config.base}/api/validateCredentials`, {
body: new FormData(this.$refs.form),
method: "post",
});
if (response.status == 200) {
this.error = false;
window.location.href = `${config.base}/`;
} else {
this.error = true;
}
},
},
};
</script>

View File

@@ -14,5 +14,10 @@
<script>
export default {
name: "PageNotFound",
metaInfo() {
return {
title: "404 Error",
};
},
};
</script>

View File

@@ -91,7 +91,6 @@
<script>
import gt from "semver/functions/gt";
import valid from "semver/functions/valid";
import { mapActions, mapState } from "vuex";
import Icon from "../components/Icon";
import config from "../store/config";

View File

@@ -4,3 +4,4 @@ export { default as Show } from "./Show.vue";
export { default as Container } from "./Container.vue";
export { default as Settings } from "./Settings.vue";
export { default as PageNotFound } from "./PageNotFound.vue";
export { default as Login } from "./Login.vue";

View File

@@ -2,8 +2,12 @@ const config = JSON.parse(document.querySelector("script#config__json").textCont
if (config.version == "{{ .Version }}") {
config.version = "dev";
config.base = "";
config.authorizationNeeded = false;
config.secured = false;
} else {
config.version = config.version.replace(/^v/, "");
config.authorizationNeeded = config.authorizationNeeded === "true";
config.secured = config.secured === "true";
}
export default config;

View File

@@ -16,6 +16,7 @@ const state = {
searchFilter: null,
isMobile: mql.matches,
settings: storage.get(DOZZLE_SETTINGS_KEY),
authorizationNeeded: config.authorizationNeeded,
};
const mutations = {
@@ -101,10 +102,12 @@ const getters = {
},
};
const es = new EventSource(`${config.base}/api/events/stream`);
es.addEventListener("containers-changed", (e) => store.commit("SET_CONTAINERS", JSON.parse(e.data)), false);
es.addEventListener("container-stat", (e) => store.dispatch("UPDATE_STATS", JSON.parse(e.data)), false);
es.addEventListener("container-die", (e) => store.dispatch("UPDATE_CONTAINER", JSON.parse(e.data)), false);
if (!config.authorizationNeeded) {
const es = new EventSource(`${config.base}/api/events/stream`);
es.addEventListener("containers-changed", (e) => store.commit("SET_CONTAINERS", JSON.parse(e.data)), false);
es.addEventListener("container-stat", (e) => store.dispatch("UPDATE_STATS", JSON.parse(e.data)), false);
es.addEventListener("container-die", (e) => store.dispatch("UPDATE_CONTAINER", JSON.parse(e.data)), false);
}
mql.addEventListener("change", (e) => store.commit("SET_MOBILE_WIDTH", e.matches));

View File

@@ -1,7 +1,7 @@
@charset "utf-8";
@import "~bulma/sass/utilities/initial-variables.sass";
$body-family: "Roboto", sans-serif;
$body-background-color: var(--body-background-color);
$scheme-main: var(--scheme-main);

16
go.mod
View File

@@ -2,40 +2,34 @@ module github.com/amir20/dozzle
require (
github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/alexflint/go-arg v1.3.0
github.com/beme/abide v0.0.0-20190723115211-635a09831760
github.com/containerd/containerd v1.4.4 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v20.10.5+incompatible
github.com/docker/docker v20.10.6+incompatible
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.0
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.1 // indirect
github.com/gorilla/mux v1.8.0
github.com/magiconair/properties v1.8.4
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/gorilla/sessions v1.2.1
github.com/magiconair/properties v1.8.5
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/pelletier/go-toml v1.8.1 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/sirupsen/logrus v1.8.1
github.com/spf13/afero v1.6.0
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.1
github.com/stretchr/objx v0.3.0 // indirect
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 // indirect
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 // indirect
golang.org/x/text v0.3.5 // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6 // indirect
google.golang.org/grpc v1.36.0 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
gotest.tools/v3 v3.0.3 // indirect
)

258
go.sum
View File

@@ -1,55 +1,28 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
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/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/alexflint/go-arg v1.3.0 h1:UfldqSdFWeLtoOuVRosqofU4nmhI1pYEbT4ZFS34Bdo=
github.com/alexflint/go-arg v1.3.0/go.mod h1:9iRbDxne7LcR/GSvEr7ma++GLpdIU1zrghf2y2768kM=
github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi+A70=
github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw=
github.com/beme/abide v0.0.0-20190723115211-635a09831760 h1:FvTM5NSN5HYvfKpgL+8x73U5v063vHsd7AX05eV1DnM=
github.com/beme/abide v0.0.0-20190723115211-635a09831760/go.mod h1:6+8gCKsZnxzhGTmKRh4BSkLos9CbWRJNcrp55We4SqQ=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/containerd/containerd v1.4.4 h1:rtRG4N6Ct7GNssATwgpvMGfnjnwfjnu/Zs9W3Ikzq+M=
github.com/containerd/containerd v1.4.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.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/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/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/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.5+incompatible h1:o5WL5onN4awYGwrW7+oTn5x9AF2prw7V0Ox8ZEkoCdg=
github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ=
github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
@@ -60,27 +33,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
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=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
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=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
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.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=
@@ -92,8 +49,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1 h1:jAbXjIeW2ZSW2AwFxlGTDoc2CjI2XujLkV3ArsZFCvc=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -101,139 +56,47 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
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=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
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/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
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/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
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.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
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/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.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.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.3.0 h1:NGXK3lHquSN08v5vWalVI/L8XU9hdzE/G6xsrze47As=
@@ -244,89 +107,39 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/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=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
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=
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-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
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=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/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=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
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=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/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-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -336,33 +149,17 @@ golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4 h1:EZ2mChiOa8udjfp6rRmswTbtZ
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
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 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/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-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-20190624222133-a101b041ded4/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-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-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -371,30 +168,14 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
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=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6 h1:4Xw2NwItrJOFR5s6PnK98PI6Bgw1LhMP1j/rO5WP0S4=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
@@ -413,22 +194,11 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
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-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
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=
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.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=
@@ -436,8 +206,4 @@ gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
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=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

@@ -7,6 +7,7 @@ services:
environment:
- DOZZLE_FILTER=name=custom_base
- DOZZLE_BASE=/foobarbase
- DOZZLE_NO_ANALYTICS=1
build:
context: ..
dozzle:
@@ -15,6 +16,7 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DOZZLE_FILTER=name=dozzle
- DOZZLE_NO_ANALYTICS=1
build:
context: ..
integration:
@@ -26,6 +28,7 @@ services:
environment:
- DEFAULT_URL=http://dozzle:8080/
- CUSTOM_URL=http://custom_base:8080/foobarbase
- DOZZLE_NO_ANALYTICS=1
depends_on:
- dozzle
- custom_base

View File

@@ -19,6 +19,6 @@
]
},
"devDependencies": {
"jest-puppeteer": "^4.4.0"
"jest-puppeteer": "^5.0.1"
}
}

View File

@@ -298,37 +298,17 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==
"@hapi/hoek@^9.0.0":
version "9.2.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131"
integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug==
"@hapi/bourne@1.x.x":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a"
integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==
"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0":
version "8.5.1"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06"
integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==
"@hapi/joi@^15.0.3":
version "15.1.1"
resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7"
integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==
"@hapi/topo@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==
dependencies:
"@hapi/address" "2.x.x"
"@hapi/bourne" "1.x.x"
"@hapi/hoek" "8.x.x"
"@hapi/topo" "3.x.x"
"@hapi/topo@3.x.x":
version "3.1.6"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29"
integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==
dependencies:
"@hapi/hoek" "^8.3.0"
"@hapi/hoek" "^9.0.0"
"@istanbuljs/load-nyc-config@^1.0.0":
version "1.0.0"
@@ -516,6 +496,23 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
"@sideway/address@^4.1.0":
version "4.1.1"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d"
integrity sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ==
dependencies:
"@hapi/hoek" "^9.0.0"
"@sideway/formula@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c"
integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==
"@sideway/pinpoint@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df"
integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==
"@sinonjs/commons@^1.7.0":
version "1.7.1"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1"
@@ -808,6 +805,13 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies:
follow-redirects "^1.10.0"
babel-jest@^26.6.3:
version "26.6.3"
resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056"
@@ -1022,7 +1026,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2:
chalk@^2.0.0, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -1031,14 +1035,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72"
@@ -1047,6 +1043,14 @@ chalk@^4.0.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a"
integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
char-regex@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
@@ -1146,16 +1150,16 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies:
delayed-stream "~1.0.0"
commander@^2.11.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e"
integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==
commander@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae"
integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==
component-emitter@^1.2.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
@@ -1178,11 +1182,6 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js@^2.6.5:
version "2.6.11"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -1256,7 +1255,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"
debug@^2.2.0, debug@^2.3.3, debug@^2.6.8:
debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
@@ -1464,10 +1463,10 @@ expand-tilde@^1.2.2:
dependencies:
os-homedir "^1.0.1"
expect-puppeteer@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/expect-puppeteer/-/expect-puppeteer-4.4.0.tgz#1c948af08acdd6c8cbdb7f90e617f44d86888886"
integrity sha512-6Ey4Xy2xvmuQu7z7YQtMsaMV0EHJRpVxIDOd5GRrm04/I3nkTKIutELfECsLp6le+b3SSa3cXhPiw6PgqzxYWA==
expect-puppeteer@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/expect-puppeteer/-/expect-puppeteer-5.0.0.tgz#e4a61bb91e3bba58030d8d66a87e5b67bb2898a9"
integrity sha512-yMzVgFfPN0GOD7YMvs9hHsf9YxRg7SrcHqENxkgznoqtRBUZDdSmUte3osJ0LpLIb+9TXP5YUbCbOj7HmCl6EQ==
expect@^26.6.2:
version "26.6.2"
@@ -1597,14 +1596,14 @@ find-pkg@^0.1.2:
dependencies:
find-file-up "^0.1.2"
find-process@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.3.tgz#25f9105dc32e42abad4636752c37c51cd57dce45"
integrity sha512-+IA+AUsQCf3uucawyTwMWcY+2M3FXq3BRvw3S+j5Jvydjk31f/+NPWpYZOJs+JUs2GvxH4Yfr6Wham0ZtRLlPA==
find-process@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.4.tgz#52820561162fda0d1feef9aed5d56b3787f0fd6e"
integrity sha512-rRSuT1LE4b+BFK588D2V8/VG9liW0Ark1XJgroxZXI0LtwmQJOb490DvDYvbm+Hek9ETFzTutGfJ90gumITPhQ==
dependencies:
chalk "^2.0.1"
commander "^2.11.0"
debug "^2.6.8"
chalk "^4.0.0"
commander "^5.1.0"
debug "^4.1.1"
find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
@@ -1614,6 +1613,11 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
follow-redirects@^1.10.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==
for-in@^0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
@@ -2216,18 +2220,18 @@ jest-config@^26.6.3:
micromatch "^4.0.2"
pretty-format "^26.6.2"
jest-dev-server@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/jest-dev-server/-/jest-dev-server-4.4.0.tgz#557113faae2877452162696aa94c1e44491ab011"
integrity sha512-STEHJ3iPSC8HbrQ3TME0ozGX2KT28lbT4XopPxUm2WimsX3fcB3YOptRh12YphQisMhfqNSNTZUmWyT3HEXS2A==
jest-dev-server@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/jest-dev-server/-/jest-dev-server-5.0.0.tgz#904ff0525715b8268d817a07d6ce942ce70d06b2"
integrity sha512-PUgOwr/XT+KUJG+bMjifSWwswQXhh92wMPGnkFZiHtWkc2IcdCCykRLkoFSKCKWPveuGDOa7ZKVoUgn0+S4wew==
dependencies:
chalk "^3.0.0"
chalk "^4.1.0"
cwd "^0.10.0"
find-process "^1.4.3"
prompts "^2.3.0"
spawnd "^4.4.0"
find-process "^1.4.4"
prompts "^2.4.1"
spawnd "^5.0.0"
tree-kill "^1.2.2"
wait-on "^3.3.0"
wait-on "^5.3.0"
jest-diff@^26.6.2:
version "26.6.2"
@@ -2282,15 +2286,16 @@ jest-environment-node@^26.6.2:
jest-mock "^26.6.2"
jest-util "^26.6.2"
jest-environment-puppeteer@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/jest-environment-puppeteer/-/jest-environment-puppeteer-4.4.0.tgz#d82a37e0e0c51b63cc6b15dea101d53967508860"
integrity sha512-iV8S8+6qkdTM6OBR/M9gKywEk8GDSOe05hspCs5D8qKSwtmlUfdtHfB4cakdc68lC6YfK3AUsLirpfgodCHjzQ==
jest-environment-puppeteer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/jest-environment-puppeteer/-/jest-environment-puppeteer-5.0.1.tgz#dc520fca625de054876181304b57c0f5879372e8"
integrity sha512-OtSNz3YOkhEGdQ02AQk1t9EbN9TcU7rbPRkcJeRj9RgwXlm5O9ijZIwi8ASd7tLKxddykdF+s8JPhynyDnLHOg==
dependencies:
chalk "^3.0.0"
chalk "^4.1.0"
cwd "^0.10.0"
jest-dev-server "^4.4.0"
merge-deep "^3.0.2"
jest-dev-server "^5.0.0"
jest-environment-node "^26.6.2"
merge-deep "^3.0.3"
jest-get-type@^26.3.0:
version "26.3.0"
@@ -2319,9 +2324,9 @@ jest-haste-map@^26.6.2:
fsevents "^2.1.2"
jest-image-snapshot@^4.0.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/jest-image-snapshot/-/jest-image-snapshot-4.4.0.tgz#7c5282cc62280086b6cbcda203d50b6ee0b0e71e"
integrity sha512-lGlHxoEHLYL0qyr6E7SA04/eMT/PFWxHRNmhEJZpw80iE1XH/wSHEKiK4oDGJI5FQ4hhWPXmcH5tDlTvsAHogQ==
version "4.4.1"
resolved "https://registry.yarnpkg.com/jest-image-snapshot/-/jest-image-snapshot-4.4.1.tgz#1ecc83ce55de9a92661bc488b795300719992808"
integrity sha512-Qdx9mGXMgmbw74YofHWny3J7yh08z+Hl+yzNt67RafpvE3bqboVCHdUDgesD5Jq83lQe0znbG7TzB3iL5DOx2A==
dependencies:
chalk "^1.1.3"
get-stdin "^5.0.1"
@@ -2403,13 +2408,13 @@ jest-pnp-resolver@^1.2.2:
resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
jest-puppeteer@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/jest-puppeteer/-/jest-puppeteer-4.4.0.tgz#4b906e638a5e3782ed865e7b673c82047b85952e"
integrity sha512-ZaiCTlPZ07B9HW0erAWNX6cyzBqbXMM7d2ugai4epBDKpKvRDpItlRQC6XjERoJELKZsPziFGS0OhhUvTvQAXA==
jest-puppeteer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/jest-puppeteer/-/jest-puppeteer-5.0.1.tgz#eaa2c38024f6e30b715a953b08ceb19960d04af3"
integrity sha512-PH0jpKgVoVqDGWZdFRG0vI/lOmsqYU8fjtJw+7U3UL6lOWkY7BNfFmE7fTlevF/IhYrRqJfeg0l1tmUGA9ck/w==
dependencies:
expect-puppeteer "^4.4.0"
jest-environment-puppeteer "^4.4.0"
expect-puppeteer "^5.0.0"
jest-environment-puppeteer "^5.0.1"
jest-regex-util@^26.0.0:
version "26.0.0"
@@ -2583,6 +2588,17 @@ jest@^26.0.1:
import-local "^3.0.2"
jest-cli "^26.6.3"
joi@^17.3.0:
version "17.4.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20"
integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo" "^5.0.0"
"@sideway/address" "^4.1.0"
"@sideway/formula" "^3.0.0"
"@sideway/pinpoint" "^2.0.0"
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@@ -2756,6 +2772,11 @@ lodash@^4.17.13, lodash@^4.17.15, lodash@^4.17.4:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
@@ -2789,10 +2810,10 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
merge-deep@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.2.tgz#f39fa100a4f1bd34ff29f7d2bf4508fbb8d83ad2"
integrity sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA==
merge-deep@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/merge-deep/-/merge-deep-3.0.3.tgz#1a2b2ae926da8b2ae93a0ac15d90cd1922766003"
integrity sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==
dependencies:
arr-union "^3.1.0"
clone-deep "^0.2.4"
@@ -3196,7 +3217,7 @@ progress@^2.0.1:
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
prompts@^2.0.1, prompts@^2.3.0:
prompts@^2.0.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.3.2.tgz#480572d89ecf39566d2bd3fe2c9fccb7c4c0b068"
integrity sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==
@@ -3204,6 +3225,14 @@ prompts@^2.0.1, prompts@^2.3.0:
kleur "^3.0.3"
sisteransi "^1.0.4"
prompts@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61"
integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==
dependencies:
kleur "^3.0.3"
sisteransi "^1.0.5"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
@@ -3322,7 +3351,7 @@ request-promise-native@^1.0.8:
stealthy-require "^1.1.1"
tough-cookie "^2.3.3"
request@^2.88.0, request@^2.88.2:
request@^2.88.2:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
@@ -3429,10 +3458,12 @@ rsvp@^4.8.4:
resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734"
integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==
rx@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=
rxjs@^6.6.3:
version "6.6.7"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
dependencies:
tslib "^1.9.0"
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.0"
@@ -3554,12 +3585,12 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
signal-exit@^3.0.0, signal-exit@^3.0.2:
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
sisteransi@^1.0.4:
sisteransi@^1.0.4, sisteransi@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed"
integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==
@@ -3638,15 +3669,15 @@ source-map@^0.7.3:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
spawnd@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/spawnd/-/spawnd-4.4.0.tgz#bb52c5b34a22e3225ae1d3acb873b2cd58af0886"
integrity sha512-jLPOfB6QOEgMOQY15Z6+lwZEhH3F5ncXxIaZ7WHPIapwNNLyjrs61okj3VJ3K6tmP5TZ6cO0VAu9rEY4MD4YQg==
spawnd@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/spawnd/-/spawnd-5.0.0.tgz#ea72200bdc468998e84e1c3e7b914ce85fc1c32c"
integrity sha512-28+AJr82moMVWolQvlAIv3JcYDkjkFTEmfDc503wxrF5l2rQ3dFz6DpbXp3kD4zmgGGldfM4xM4v1sFj/ZaIOA==
dependencies:
exit "^0.1.2"
signal-exit "^3.0.2"
signal-exit "^3.0.3"
tree-kill "^1.2.2"
wait-port "^0.2.7"
wait-port "^0.2.9"
spdx-correct@^3.0.0:
version "3.1.1"
@@ -3930,6 +3961,11 @@ tree-kill@^1.2.2:
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
@@ -4074,21 +4110,21 @@ w3c-xmlserializer@^2.0.0:
dependencies:
xml-name-validator "^3.0.0"
wait-on@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082"
integrity sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ==
wait-on@^5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-5.3.0.tgz#584e17d4b3fe7b46ac2b9f8e5e102c005c2776c7"
integrity sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==
dependencies:
"@hapi/joi" "^15.0.3"
core-js "^2.6.5"
minimist "^1.2.0"
request "^2.88.0"
rx "^4.1.0"
axios "^0.21.1"
joi "^17.3.0"
lodash "^4.17.21"
minimist "^1.2.5"
rxjs "^6.6.3"
wait-port@^0.2.7:
version "0.2.7"
resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-0.2.7.tgz#cdb4b78e662328099b187c7bb75fe0aa9cb6eb6c"
integrity sha512-pJ6cSBIa0w1sDg4y/wXN4bmvhM9OneOvwdFHo647L2NShBi/oXG4lRaLic5cO1HaYGbUhEvratPfl/WMlIC+tg==
wait-port@^0.2.9:
version "0.2.9"
resolved "https://registry.yarnpkg.com/wait-port/-/wait-port-0.2.9.tgz#3905cf271b5dbe37a85c03b85b418b81cb24ee55"
integrity sha512-hQ/cVKsNqGZ/UbZB/oakOGFqic00YAMM5/PEj3Bt4vKarv2jWIWzDbqlwT94qMs/exAQAsvMOq99sZblV92zxQ==
dependencies:
chalk "^2.4.2"
commander "^3.0.2"

135
main.go
View File

@@ -4,58 +4,61 @@ import (
"context"
"embed"
"io/fs"
"net/http"
_ "net/http/pprof"
"net/url"
"os"
"os/signal"
"strings"
"syscall"
"time"
"github.com/alexflint/go-arg"
"github.com/amir20/dozzle/analytics"
"github.com/amir20/dozzle/docker"
"github.com/amir20/dozzle/web"
log "github.com/sirupsen/logrus"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)
var (
addr = ""
base = ""
level = ""
tailSize = 300
filters map[string]string
version = "dev"
filters map[string]string
version = "dev"
)
type args struct {
Addr string `arg:"env:DOZZLE_ADDR" default:":8080"`
Base string `arg:"env:DOZZLE_BASE" default:"/"`
Level string `arg:"env:DOZZLE_LEVEL" default:"info"`
TailSize int `arg:"env:DOZZLE_TAILSIZE" default:"300"`
Filter string `arg:"env:DOZZLE_FILTER"`
Key string `arg:"env:DOZZLE_KEY"`
Username string `arg:"env:DOZZLE_USERNAME"`
Password string `arg:"env:DOZZLE_PASSWORD"`
NoAnalytics bool `arg:"--no-analytics,env:DOZZLE_NO_ANALYTICS"`
}
func (args) Version() string {
return version
}
//go:embed static
var content embed.FS
type handler struct {
client docker.Client
}
func main() {
var args args
arg.MustParse(&args)
level, _ := log.ParseLevel(args.Level)
log.SetLevel(level)
func init() {
pflag.String("addr", ":8080", "http service address")
pflag.String("base", "/", "base address of the application to mount")
pflag.String("level", "info", "logging level")
pflag.Int("tailSize", 300, "Tail size to use for initial container logs")
pflag.StringToStringVar(&filters, "filter", map[string]string{}, "Container filters to use for showing logs")
pflag.Parse()
log.SetFormatter(&log.TextFormatter{
DisableTimestamp: true,
DisableLevelTruncation: true,
})
viper.AutomaticEnv()
viper.SetEnvPrefix("DOZZLE")
viper.BindPFlags(pflag.CommandLine)
addr = viper.GetString("addr")
base = viper.GetString("base")
level = viper.GetString("level")
tailSize = viper.GetInt("tailSize")
// Until https://github.com/spf13/viper/issues/911 is fixed. We have to use this hacky way.
// filters = viper.GetStringMapString("filter")
if value, ok := os.LookupEnv("DOZZLE_FILTER"); ok {
log.Infof("Parsing %s", value)
urlValues, err := url.ParseQuery(strings.ReplaceAll(value, ",", "&"))
if args.Filter != "" {
log.Infof("Parsing %s", args.Filter)
urlValues, err := url.ParseQuery(strings.ReplaceAll(args.Filter, ",", "&"))
if err != nil {
log.Fatal(err)
}
@@ -65,16 +68,6 @@ func init() {
}
}
l, _ := log.ParseLevel(level)
log.SetLevel(l)
log.SetFormatter(&log.TextFormatter{
DisableTimestamp: true,
DisableLevelTruncation: true,
})
}
func main() {
log.Infof("Dozzle version %s", version)
dockerClient := docker.NewClientWithFilters(filters)
_, err := dockerClient.ListContainers()
@@ -83,11 +76,24 @@ func main() {
log.Fatalf("Could not connect to Docker Engine: %v", err)
}
if args.Username != "" || args.Password != "" {
if args.Username == "" || args.Password == "" {
log.Fatalf("Username AND password are required for authentication")
}
if args.Key == "" {
log.Fatalf("Key is required for authentication")
}
}
config := web.Config{
Addr: addr,
Base: base,
Addr: args.Addr,
Base: args.Base,
Version: version,
TailSize: tailSize,
TailSize: args.TailSize,
Key: args.Key,
Username: args.Username,
Password: args.Password,
}
static, err := fs.Sub(content, "static")
@@ -95,22 +101,53 @@ func main() {
log.Fatalf("Could not open embedded static folder: %v", err)
}
srv := web.CreateServer(dockerClient, static, config)
if _, ok := os.LookupEnv("LIVE_FS"); ok {
log.Info("Using live filesystem at ./static")
static = os.DirFS("./static")
}
srv := web.CreateServer(dockerClient, static, config)
go doStartEvent(args)
go func() {
log.Infof("Accepting connections on %s", srv.Addr)
if err := srv.ListenAndServe(); err != nil {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatal(err)
}
}()
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt)
signal.Notify(c, os.Kill)
signal.Notify(c, syscall.SIGTERM)
<-c
log.Infof("Shutting down...")
log.Info("Shutting down...")
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
srv.Shutdown(ctx)
os.Exit(0)
}
func doStartEvent(arg args) {
if arg.NoAnalytics {
log.Debug("Analytics disabled.")
return
}
host, err := os.Hostname()
if err != nil {
log.Debug(err)
return
}
event := analytics.StartEvent{
ClientId: host,
Version: version,
FilterLength: len(filters),
CustomAddress: arg.Addr != ":8080",
CustomBase: arg.Base != "/",
TailSize: arg.TailSize,
Protected: arg.Username != "",
}
if err := analytics.SendStartEvent(event); err != nil {
log.Debug(err)
}
}

View File

@@ -1,11 +1,11 @@
{
"name": "dozzle",
"version": "3.4.5",
"version": "3.6.1",
"description": "Realtime log viewer for docker containers. ",
"scripts": {
"watch": "npm-run-all -p watch:*",
"watch:assets": "webpack --mode=development --watch",
"watch:server": "reflex -c .reflex",
"watch:server": "LIVE_FS=true reflex -c .reflex",
"predev": "make fake_static",
"dev": "npm-run-all -p dev-server watch:server",
"dev-server": "webpack serve --mode=development",
@@ -28,9 +28,9 @@
"homepage": "https://github.com/amir20/dozzle#readme",
"dependencies": {
"ansi-to-html": "^0.6.14",
"buefy": "^0.9.5",
"buefy": "^0.9.6",
"bulma": "^0.9.2",
"date-fns": "^2.19.0",
"date-fns": "^2.21.1",
"dompurify": "^2.2.7",
"fuzzysort": "^1.1.4",
"hotkeys-js": "^3.8.3",
@@ -45,36 +45,36 @@
"vuex": "^3.6.2"
},
"devDependencies": {
"@babel/core": "^7.13.14",
"@babel/plugin-transform-runtime": "^7.13.10",
"@babel/core": "^7.13.15",
"@babel/plugin-transform-runtime": "^7.13.15",
"@vue/component-compiler-utils": "^3.2.0",
"@vue/test-utils": "^1.1.3",
"@vue/test-utils": "^1.1.4",
"autoprefixer": "^10.2.5",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^26.6.3",
"babel-preset-env": "^1.7.0",
"caniuse-lite": "^1.0.30001205",
"css-loader": "^5.2.0",
"caniuse-lite": "^1.0.30001210",
"css-loader": "^5.2.2",
"eventsourcemock": "^2.0.0",
"html-webpack-plugin": "^5.3.1",
"husky": "^6.0.0",
"jest": "^26.6.3",
"jest-serializer-vue": "^2.0.2",
"lint-staged": "^10.5.4",
"mini-css-extract-plugin": "^1.4.0",
"mini-css-extract-plugin": "^1.5.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.2.9",
"postcss": "^8.2.10",
"postcss-loader": "^5.2.0",
"prettier": "^2.2.1",
"release-it": "^14.5.0",
"sass": "^1.32.8",
"release-it": "^14.6.1",
"sass": "^1.32.10",
"sass-loader": "^11.0.1",
"vue-hot-reload-api": "^2.3.4",
"vue-jest": "^3.0.7",
"vue-loader": "^15.9.6",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.12",
"webpack": "^5.28.0",
"webpack": "^5.33.2",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^3.11.2",
"webpack-pwa-manifest": "^4.3.0"
@@ -86,7 +86,8 @@
},
"release-it": {
"github": {
"release": false
"release": false,
"releaseNotes": "git log --pretty=format:\"* %s (%h)\" $(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1))...HEAD~1"
},
"npm": {
"publish": false

View File

@@ -23,6 +23,36 @@ Location: /foobar/
<a href="/foobar/">Moved Permanently</a>.
/* snapshot: Test_createRoutes_username_password */
HTTP/1.1 307 Temporary Redirect
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; manifest-src 'self'; connect-src 'self' api.github.com; require-trusted-types-for 'script'
Content-Type: text/html; charset=utf-8
Location: /login
<a href="/login">Temporary Redirect</a>.
/* snapshot: Test_createRoutes_username_password_invalid */
HTTP/1.1 401 Unauthorized
Connection: close
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; manifest-src 'self'; connect-src 'self' api.github.com; require-trusted-types-for 'script'
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Unauthorized
/* snapshot: Test_createRoutes_username_password_valid_session */
HTTP/1.1 200 OK
Connection: close
Cache-Control: no-cache
Connection: keep-alive
Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; manifest-src 'self'; connect-src 'self' api.github.com; require-trusted-types-for 'script'
Content-Type: text/event-stream
X-Accel-Buffering: no
event: container-stopped
data: end of stream
/* snapshot: Test_createRoutes_version */
HTTP/1.1 200 OK
Connection: close

116
web/auth.go Normal file
View File

@@ -0,0 +1,116 @@
package web
import (
"net/http"
"time"
"github.com/gorilla/sessions"
log "github.com/sirupsen/logrus"
)
var secured = false
var store *sessions.CookieStore
const authorityKey = "AUTH_TIMESTAMP"
const sessionName = "session"
func initializeAuth(h *handler) {
if h.config.Username != "" && h.config.Password != "" {
store = sessions.NewCookieStore([]byte(h.config.Key))
store.Options.HttpOnly = true
store.Options.SameSite = http.SameSiteLaxMode
store.Options.MaxAge = 0
secured = true
}
}
func authorizationRequired(f http.HandlerFunc) http.Handler {
if secured {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if isAuthorized(r) {
f(w, r)
} else {
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
})
} else {
return http.HandlerFunc(f)
}
}
func isAuthorized(r *http.Request) bool {
if !secured {
return true
}
session, _ := store.Get(r, sessionName)
if session.IsNew {
return false
}
if _, ok := session.Values[authorityKey]; ok {
// TODO check for timestamp
return true
}
return false
}
func (h *handler) isAuthorizationNeeded(r *http.Request) bool {
return secured && !isAuthorized(r)
}
func (h *handler) validateCredentials(w http.ResponseWriter, r *http.Request) {
if !secured {
log.Panic("Validating credentials without username and password should not happen")
}
if r.Method != "POST" {
log.Fatal("Expecting credential validation method to be POST")
http.Error(w, http.StatusText(http.StatusNotAcceptable), http.StatusNotAcceptable)
return
}
if err := r.ParseMultipartForm(4 * 1024); err != nil {
log.Fatalf("Error while parsing form data: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
user := r.PostFormValue("username")
pass := r.PostFormValue("password")
session, _ := store.Get(r, sessionName)
if user == h.config.Username && pass == h.config.Password {
session.Values[authorityKey] = time.Now().Unix()
if err := session.Save(r, w); err != nil {
log.Fatalf("Error while parsing saving session: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(http.StatusText(http.StatusOK)))
return
}
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
}
func (h *handler) clearSession(w http.ResponseWriter, r *http.Request) {
if !secured {
log.Panic("Validating credentials with secured=false should not happen")
}
session, _ := store.Get(r, sessionName)
delete(session.Values, authorityKey)
if err := session.Save(r, w); err != nil {
log.Fatalf("Error while parsing saving session: %v", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, h.config.Base, http.StatusTemporaryRedirect)
}

12
web/csp.go Normal file
View File

@@ -0,0 +1,12 @@
package web
import (
"net/http"
)
func cspHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Security-Policy", "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; manifest-src 'self'; connect-src 'self' api.github.com; require-trusted-types-for 'script'")
next.ServeHTTP(w, r)
})
}

110
web/events.go Normal file
View File

@@ -0,0 +1,110 @@
package web
import (
"encoding/json"
"fmt"
"net/http"
"github.com/amir20/dozzle/docker"
log "github.com/sirupsen/logrus"
)
func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
ctx := r.Context()
events, err := h.client.Events(ctx)
stats := make(chan docker.ContainerStat)
if containers, err := h.client.ListContainers(); err == nil {
for _, c := range containers {
if c.State == "running" {
if err := h.client.ContainerStats(ctx, c.ID, stats); err != nil {
log.Errorf("error while streaming container stats: %v", err)
}
}
}
}
if err := sendContainersJSON(h.client, w); err != nil {
log.Errorf("error while encoding containers to stream: %v", err)
}
f.Flush()
for {
select {
case stat := <-stats:
bytes, _ := json.Marshal(stat)
if _, err := fmt.Fprintf(w, "event: container-stat\ndata: %s\n\n", string(bytes)); err != nil {
log.Errorf("error writing stat to event stream: %v", err)
return
}
f.Flush()
case event, ok := <-events:
if !ok {
return
}
switch event.Name {
case "start", "die":
log.Debugf("triggering docker event: %v", event.Name)
if event.Name == "start" {
log.Debugf("found new container with id: %v", event.ActorID)
if err := h.client.ContainerStats(ctx, event.ActorID, stats); err != nil {
log.Errorf("error when streaming new container stats: %v", err)
}
if err := sendContainersJSON(h.client, w); err != nil {
log.Errorf("error encoding containers to stream: %v", err)
return
}
}
bytes, _ := json.Marshal(event)
if _, err := fmt.Fprintf(w, "event: container-%s\ndata: %s\n\n", event.Name, string(bytes)); err != nil {
log.Errorf("error writing event to event stream: %v", err)
return
}
f.Flush()
default:
// do nothing
}
case <-ctx.Done():
return
case <-err:
return
}
}
}
func sendContainersJSON(client docker.Client, w http.ResponseWriter) error {
containers, err := client.ListContainers()
if err != nil {
return err
}
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
return err
}
if err := json.NewEncoder(w).Encode(containers); err != nil {
return err
}
if _, err := fmt.Fprint(w, "\n\n"); err != nil {
return err
}
return nil
}

145
web/logs.go Normal file
View File

@@ -0,0 +1,145 @@
package web
import (
"bufio"
"compress/gzip"
"context"
"fmt"
"io"
"net/http"
"runtime"
"strings"
"time"
"github.com/dustin/go-humanize"
log "github.com/sirupsen/logrus"
)
func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
from, _ := time.Parse(time.RFC3339, r.URL.Query().Get("from"))
to, _ := time.Parse(time.RFC3339, r.URL.Query().Get("to"))
id := r.URL.Query().Get("id")
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), id, from, to)
defer reader.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(w, reader)
}
func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
now := time.Now()
from := time.Unix(container.Created, 0)
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%v.log.gz", container.ID))
w.Header().Set("Content-Type", "application/gzip")
zw := gzip.NewWriter(w)
defer zw.Close()
zw.Name = fmt.Sprintf("%v.log", container.ID)
zw.Comment = "Logs generated by Dozzle"
zw.ModTime = now
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), container.ID, from, now)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(zw, reader)
}
func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
http.Error(w, "id is required", http.StatusBadRequest)
return
}
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
reader, err := h.client.ContainerLogs(r.Context(), container.ID, h.config.TailSize, r.Header.Get("Last-Event-ID"))
if err != nil {
if err == io.EOF {
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
defer reader.Close()
buffered := bufio.NewReader(reader)
var readerError error
var message string
for {
message, readerError = buffered.ReadString('\n')
fmt.Fprintf(w, "data: %s\n", message)
if index := strings.IndexAny(message, " "); index != -1 {
id := message[:index]
if _, err := time.Parse(time.RFC3339Nano, id); err == nil {
fmt.Fprintf(w, "id: %s\n", id)
}
}
fmt.Fprintf(w, "\n")
f.Flush()
if readerError != nil {
break
}
}
log.Debugf("streaming stopped: %v", container.ID)
if readerError == io.EOF {
log.Debugf("container stopped: %v", container.ID)
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else if readerError != context.Canceled {
log.Errorf("unknown error while streaming %v", readerError.Error())
}
log.WithField("routines", runtime.NumGoroutine()).Debug("runtime goroutine stats")
if log.IsLevelEnabled(log.DebugLevel) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
log.WithFields(log.Fields{
"allocated": humanize.Bytes(m.Alloc),
"totalAllocated": humanize.Bytes(m.TotalAlloc),
"system": humanize.Bytes(m.Sys),
}).Debug("runtime mem stats")
}
}

View File

@@ -1,25 +1,13 @@
package web
import (
"bufio"
"compress/gzip"
"context"
"encoding/json"
"fmt"
"html/template"
"io"
"io/fs"
"io/ioutil"
"net/http"
_ "net/http/pprof"
"runtime"
"strings"
"time"
"github.com/amir20/dozzle/docker"
"github.com/dustin/go-humanize"
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
@@ -31,13 +19,15 @@ type Config struct {
Addr string
Version string
TailSize int
Key string
Username string
Password string
}
type handler struct {
client docker.Client
content fs.FS
config *Config
fileServer http.Handler
client docker.Client
content fs.FS
config *Config
}
// CreateServer creates a service for http handler
@@ -50,21 +40,27 @@ func CreateServer(c docker.Client, content fs.FS, config Config) *http.Server {
return &http.Server{Addr: config.Addr, Handler: createRouter(handler)}
}
var fileServer http.Handler
func createRouter(h *handler) *mux.Router {
initializeAuth(h)
base := h.config.Base
r := mux.NewRouter()
r.Use(setCSPHeaders)
r.Use(cspHeaders)
if base != "/" {
r.HandleFunc(base, http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
http.Redirect(w, req, base+"/", http.StatusMovedPermanently)
}))
}
s := r.PathPrefix(base).Subrouter()
s.HandleFunc("/api/logs/stream", h.streamLogs)
s.HandleFunc("/api/logs/download", h.downloadLogs)
s.HandleFunc("/api/logs", h.fetchLogsBetweenDates)
s.HandleFunc("/api/events/stream", h.streamEvents)
s.HandleFunc("/version", h.version)
s.Handle("/api/logs/stream", authorizationRequired(h.streamLogs))
s.Handle("/api/logs/download", authorizationRequired(h.downloadLogs))
s.Handle("/api/logs", authorizationRequired(h.fetchLogsBetweenDates))
s.Handle("/api/events/stream", authorizationRequired(h.streamEvents))
s.HandleFunc("/api/validateCredentials", h.validateCredentials)
s.Handle("/logout", authorizationRequired(h.clearSession))
s.Handle("/version", authorizationRequired(h.version))
if log.IsLevelEnabled(log.DebugLevel) {
s.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux)
@@ -76,270 +72,61 @@ func createRouter(h *handler) *mux.Router {
s.PathPrefix("/").Handler(http.StripPrefix(base, http.HandlerFunc(h.index)))
}
h.fileServer = http.FileServer(http.FS(h.content))
fileServer = http.FileServer(http.FS(h.content))
return r
}
func setCSPHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Security-Policy", "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self'; manifest-src 'self'; connect-src 'self' api.github.com; require-trusted-types-for 'script'")
next.ServeHTTP(w, r)
})
}
func (h *handler) index(w http.ResponseWriter, req *http.Request) {
_, err := h.content.Open(req.URL.Path)
if err == nil && req.URL.Path != "" && req.URL.Path != "/" {
h.fileServer.ServeHTTP(w, req)
fileServer.ServeHTTP(w, req)
} else {
file, err := h.content.Open("index.html")
if err != nil {
panic(err)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
panic(err)
}
tmpl, err := template.New("index.html").Parse(string(bytes))
if err != nil {
panic(err)
}
path := ""
if h.config.Base != "/" {
path = h.config.Base
}
data := struct {
Base string
Version string
}{path, h.config.Version}
err = tmpl.Execute(w, data)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
}
func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
from, _ := time.Parse(time.RFC3339, r.URL.Query().Get("from"))
to, _ := time.Parse(time.RFC3339, r.URL.Query().Get("to"))
id := r.URL.Query().Get("id")
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), id, from, to)
defer reader.Close()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(w, reader)
}
func (h *handler) downloadLogs(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
now := time.Now()
from := time.Unix(container.Created, 0)
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%v.log.gz", container.ID))
w.Header().Set("Content-Type", "application/gzip")
zw := gzip.NewWriter(w)
defer zw.Close()
zw.Name = fmt.Sprintf("%v.log", container.ID)
zw.Comment = "Logs generated by Dozzle"
zw.ModTime = now
reader, err := h.client.ContainerLogsBetweenDates(r.Context(), container.ID, from, now)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
io.Copy(zw, reader)
}
func (h *handler) streamLogs(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if id == "" {
http.Error(w, "id is required", http.StatusBadRequest)
return
}
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
container, err := h.client.FindContainer(id)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
reader, err := h.client.ContainerLogs(r.Context(), container.ID, h.config.TailSize, r.Header.Get("Last-Event-ID"))
if err != nil {
if err == io.EOF {
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
defer reader.Close()
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
message := scanner.Text()
fmt.Fprintf(w, "data: %s\n", message)
if index := strings.IndexAny(message, " "); index != -1 {
id := message[:index]
if _, err := time.Parse(time.RFC3339Nano, id); err == nil {
fmt.Fprintf(w, "id: %s\n", id)
}
}
fmt.Fprintf(w, "\n")
f.Flush()
}
log.Debugf("streaming stopped: %v", container.ID)
if scanner.Err() == nil {
log.Debugf("container stopped: %v", container.ID)
fmt.Fprintf(w, "event: container-stopped\ndata: end of stream\n\n")
f.Flush()
} else if scanner.Err() != context.Canceled {
log.Errorf("unknown error while streaming %v", scanner.Err())
}
log.WithField("routines", runtime.NumGoroutine()).Debug("runtime goroutine stats")
if log.IsLevelEnabled(log.DebugLevel) {
var m runtime.MemStats
runtime.ReadMemStats(&m)
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
log.WithFields(log.Fields{
"allocated": humanize.Bytes(m.Alloc),
"totalAllocated": humanize.Bytes(m.TotalAlloc),
"system": humanize.Bytes(m.Sys),
}).Debug("runtime mem stats")
}
}
func (h *handler) streamEvents(w http.ResponseWriter, r *http.Request) {
f, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("X-Accel-Buffering", "no")
ctx := r.Context()
events, err := h.client.Events(ctx)
stats := make(chan docker.ContainerStat)
if containers, err := h.client.ListContainers(); err == nil {
for _, c := range containers {
if c.State == "running" {
if err := h.client.ContainerStats(ctx, c.ID, stats); err != nil {
log.Errorf("error while streaming container stats: %v", err)
}
}
}
}
if err := sendContainersJSON(h.client, w); err != nil {
log.Errorf("error while encoding containers to stream: %v", err)
}
f.Flush()
for {
select {
case stat := <-stats:
bytes, _ := json.Marshal(stat)
if _, err := fmt.Fprintf(w, "event: container-stat\ndata: %s\n\n", string(bytes)); err != nil {
log.Errorf("error writing stat to event stream: %v", err)
return
}
f.Flush()
case event, ok := <-events:
if !ok {
return
}
switch event.Name {
case "start", "die":
log.Debugf("triggering docker event: %v", event.Name)
if event.Name == "start" {
log.Debugf("found new container with id: %v", event.ActorID)
if err := h.client.ContainerStats(ctx, event.ActorID, stats); err != nil {
log.Errorf("error when streaming new container stats: %v", err)
}
if err := sendContainersJSON(h.client, w); err != nil {
log.Errorf("error encoding containers to stream: %v", err)
return
}
}
bytes, _ := json.Marshal(event)
if _, err := fmt.Fprintf(w, "event: container-%s\ndata: %s\n\n", event.Name, string(bytes)); err != nil {
log.Errorf("error writing event to event stream: %v", err)
return
}
f.Flush()
default:
// do nothing
}
case <-ctx.Done():
return
case <-err:
if !isAuthorized(req) && req.URL.Path != "login" {
http.Redirect(w, req, h.config.Base+"login", http.StatusTemporaryRedirect)
return
}
h.executeTemplate(w, req)
}
}
func (h *handler) executeTemplate(w http.ResponseWriter, req *http.Request) {
file, err := h.content.Open("index.html")
if err != nil {
log.Panic(err)
}
bytes, err := ioutil.ReadAll(file)
if err != nil {
log.Panic(err)
}
tmpl, err := template.New("index.html").Parse(string(bytes))
if err != nil {
log.Panic(err)
}
path := ""
if h.config.Base != "/" {
path = h.config.Base
}
data := struct {
Base string
Version string
AuthorizationNeeded bool
Secured bool
}{
path,
h.config.Version,
h.isAuthorizationNeeded(req),
secured,
}
err = tmpl.Execute(w, data)
if err != nil {
log.Panic(err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func (h *handler) version(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%v", h.config.Version)
}
func sendContainersJSON(client docker.Client, w http.ResponseWriter) error {
containers, err := client.ListContainers()
if err != nil {
return err
}
if _, err := fmt.Fprint(w, "event: containers-changed\ndata: "); err != nil {
return err
}
if err := json.NewEncoder(w).Encode(containers); err != nil {
return err
}
if _, err := fmt.Fprint(w, "\n\n"); err != nil {
return err
}
return nil
}

View File

@@ -1,16 +1,21 @@
package web
import (
"bytes"
"context"
"errors"
"io"
"io/fs"
"io/ioutil"
"mime/multipart"
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"
"time"
"github.com/gorilla/mux"
"github.com/magiconair/properties/assert"
"github.com/amir20/dozzle/docker"
@@ -238,14 +243,9 @@ func Test_handler_streamEvents_error_request(t *testing.T) {
}
func Test_createRoutes_index(t *testing.T) {
mockedClient := new(MockedClient)
fs := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
handler := createRouter(&handler{
client: mockedClient,
content: afero.NewIOFS(fs),
config: &Config{Base: "/"},
})
handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/"})
req, err := http.NewRequest("GET", "/", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
@@ -255,15 +255,10 @@ func Test_createRoutes_index(t *testing.T) {
}
func Test_createRoutes_redirect(t *testing.T) {
mockedClient := new(MockedClient)
fs := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
handler := createRouter(&handler{
client: mockedClient,
content: afero.NewIOFS(fs),
config: &Config{Base: "/foobar"},
})
handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/foobar"})
req, err := http.NewRequest("GET", "/foobar", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
@@ -273,15 +268,9 @@ func Test_createRoutes_redirect(t *testing.T) {
}
func Test_createRoutes_foobar(t *testing.T) {
mockedClient := new(MockedClient)
fs := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fs, "index.html", []byte("foo page"), 0644), "WriteFile should have no error.")
handler := createRouter(&handler{
client: mockedClient,
content: afero.NewIOFS(fs),
config: &Config{Base: "/foobar"},
})
handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/foobar"})
req, err := http.NewRequest("GET", "/foobar/", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
@@ -291,17 +280,11 @@ func Test_createRoutes_foobar(t *testing.T) {
}
func Test_createRoutes_foobar_file(t *testing.T) {
mockedClient := new(MockedClient)
fs := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
require.NoError(t, afero.WriteFile(fs, "test", []byte("test page"), 0644), "WriteFile should have no error.")
handler := createRouter(&handler{
client: mockedClient,
content: afero.NewIOFS(fs),
config: &Config{Base: "/foobar"},
fileServer: nil,
})
handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/foobar"})
req, err := http.NewRequest("GET", "/foobar/test", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
@@ -311,15 +294,9 @@ func Test_createRoutes_foobar_file(t *testing.T) {
}
func Test_createRoutes_version(t *testing.T) {
mockedClient := new(MockedClient)
fs := afero.NewMemMapFs()
require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
handler := createRouter(&handler{
client: mockedClient,
content: afero.NewIOFS(fs),
config: &Config{Base: "/", Version: "dev"},
})
handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/", Version: "dev"})
req, err := http.NewRequest("GET", "/version", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
@@ -328,6 +305,137 @@ func Test_createRoutes_version(t *testing.T) {
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
}
func Test_createRoutes_username_password(t *testing.T) {
handler := createHandler(nil, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
req, err := http.NewRequest("GET", "/", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
}
func Test_createRoutes_username_password_invalid(t *testing.T) {
handler := createHandler(nil, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
req, err := http.NewRequest("GET", "/api/logs/stream?id=123", nil)
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
}
func Test_createRoutes_username_password_login_happy(t *testing.T) {
handler := createHandler(nil, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
fw, err := writer.CreateFormField("username")
require.NoError(t, err, "Creating field should not be error.")
_, err = io.Copy(fw, strings.NewReader("amir"))
require.NoError(t, err, "Copying field should not result in error.")
fw, err = writer.CreateFormField("password")
require.NoError(t, err, "Creating field should not be error.")
_, err = io.Copy(fw, strings.NewReader("password"))
require.NoError(t, err, "Copying field should not result in error.")
writer.Close()
req, err := http.NewRequest("POST", "/api/validateCredentials", bytes.NewReader(body.Bytes()))
req.Header.Set("Content-Type", writer.FormDataContentType())
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, rr.Code, 200)
cookie := rr.Header().Get("Set-Cookie")
assert.Matches(t, cookie, "session=.+")
}
func Test_createRoutes_username_password_login_failed(t *testing.T) {
handler := createHandler(nil, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
fw, err := writer.CreateFormField("username")
require.NoError(t, err, "Creating field should not be error.")
_, err = io.Copy(fw, strings.NewReader("amir"))
require.NoError(t, err, "Copying field should not result in error.")
fw, err = writer.CreateFormField("password")
require.NoError(t, err, "Creating field should not be error.")
_, err = io.Copy(fw, strings.NewReader("bad"))
require.NoError(t, err, "Copying field should not result in error.")
writer.Close()
req, err := http.NewRequest("POST", "/api/validateCredentials", bytes.NewReader(body.Bytes()))
req.Header.Set("Content-Type", writer.FormDataContentType())
require.NoError(t, err, "NewRequest should not return an error.")
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, rr.Code, 401)
}
func Test_createRoutes_username_password_valid_session(t *testing.T) {
mockedClient := new(MockedClient)
mockedClient.On("FindContainer", "123").Return(docker.Container{ID: "123"}, nil)
mockedClient.On("ContainerLogs", mock.Anything, "123", 0).Return(ioutil.NopCloser(strings.NewReader("test data")), io.EOF)
handler := createHandler(mockedClient, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
// Get cookie first
req, err := http.NewRequest("GET", "/api/logs/stream?id=123", nil)
require.NoError(t, err, "NewRequest should not return an error.")
session, _ := store.Get(req, sessionName)
session.Values[authorityKey] = time.Now().Unix()
recorder := httptest.NewRecorder()
session.Save(req, recorder)
cookies := recorder.Result().Cookies()
// Test with cookie
req, err = http.NewRequest("GET", "/api/logs/stream?id=123", nil)
require.NoError(t, err, "NewRequest should not return an error.")
req.AddCookie(cookies[0])
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
abide.AssertHTTPResponse(t, t.Name(), rr.Result())
}
func Test_createRoutes_username_password_invalid_session(t *testing.T) {
mockedClient := new(MockedClient)
mockedClient.On("FindContainer", "123").Return(docker.Container{ID: "123"}, nil)
mockedClient.On("ContainerLogs", mock.Anything, "123", 0).Return(ioutil.NopCloser(strings.NewReader("test data")), io.EOF)
handler := createHandler(mockedClient, nil, Config{Base: "/", Username: "amir", Password: "password", Key: "key"})
req, err := http.NewRequest("GET", "/api/logs/stream?id=123", nil)
require.NoError(t, err, "NewRequest should not return an error.")
req.AddCookie(&http.Cookie{Name: "session", Value: "baddata"})
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, rr.Code, 401)
}
func createHandler(client docker.Client, content fs.FS, config Config) *mux.Router {
if client == nil {
client = new(MockedClient)
}
if content == nil {
fs := afero.NewMemMapFs()
afero.WriteFile(fs, "index.html", []byte("index page"), 0644)
content = afero.NewIOFS(fs)
}
return createRouter(&handler{
client: client,
content: content,
config: &config,
})
}
func TestMain(m *testing.M) {
exit := m.Run()
abide.Cleanup()

318
yarn.lock
View File

@@ -9,29 +9,29 @@
dependencies:
"@babel/highlight" "^7.12.13"
"@babel/compat-data@^7.13.0":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.0.tgz#7889eb7ee6518e2afa5d312b15fd7fd1fe9f3744"
integrity sha512-mKgFbYQ+23pjwNGBNPNWrBfa3g/EcmrPnwQpjWoNxq9xYf+M8wcLhMlz/wkWimLjzNzGnl3D+C2186gMzk0VuA==
"@babel/compat-data@^7.13.11":
version "7.13.15"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.15.tgz#7e8eea42d0b64fda2b375b22d06c605222e848f4"
integrity sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==
"@babel/compat-data@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.12.tgz#a8a5ccac19c200f9dd49624cac6e19d7be1236a1"
integrity sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==
"@babel/core@^7.1.0", "@babel/core@^7.13.14", "@babel/core@^7.7.5":
version "7.13.14"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.14.tgz#8e46ebbaca460a63497c797e574038ab04ae6d06"
integrity sha512-wZso/vyF4ki0l0znlgM4inxbdrUvCb+cVz8grxDq+6C9k6qbqoIJteQOKicaKjCipU3ISV+XedCqpL2RJJVehA==
"@babel/core@^7.1.0", "@babel/core@^7.13.15", "@babel/core@^7.7.5":
version "7.13.15"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.15.tgz#a6d40917df027487b54312202a06812c4f7792d0"
integrity sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.13.9"
"@babel/helper-compilation-targets" "^7.13.13"
"@babel/helper-module-transforms" "^7.13.14"
"@babel/helpers" "^7.13.10"
"@babel/parser" "^7.13.13"
"@babel/parser" "^7.13.15"
"@babel/template" "^7.12.13"
"@babel/traverse" "^7.13.13"
"@babel/traverse" "^7.13.15"
"@babel/types" "^7.13.14"
convert-source-map "^1.7.0"
debug "^4.1.0"
@@ -59,10 +59,10 @@
browserslist "^4.14.5"
semver "^6.3.0"
"@babel/helper-define-polyfill-provider@^0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.2.tgz#619f01afe1deda460676c25c463b42eaefdb71a2"
integrity sha512-hWeolZJivTNGHXHzJjQz/NwDaG4mGXf22ZroOP8bQYgvHNzaQ5tylsVbAcAS2oDjXBwpu8qH2I/654QFS2rDpw==
"@babel/helper-define-polyfill-provider@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.0.tgz#a640051772045fedaaecc6f0c6c69f02bdd34bf1"
integrity sha512-JT8tHuFjKBo8NnaUbblz7mIu1nnvUDiHVjXXkulZULyidvo/7P6TY7+YqpV37IfF+KUFxmlK04elKtGKXaiVgw==
dependencies:
"@babel/helper-compilation-targets" "^7.13.0"
"@babel/helper-module-imports" "^7.12.13"
@@ -96,14 +96,7 @@
dependencies:
"@babel/types" "^7.13.12"
"@babel/helper-module-imports@^7.12.13":
version "7.12.13"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0"
integrity sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==
dependencies:
"@babel/types" "^7.12.13"
"@babel/helper-module-imports@^7.13.12":
"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977"
integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==
@@ -188,10 +181,10 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.13":
version "7.13.13"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df"
integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw==
"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.15":
version "7.13.15"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.15.tgz#8e66775fb523599acb6a289e12929fa5ab0954d8"
integrity sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==
"@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4"
@@ -277,16 +270,16 @@
dependencies:
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-transform-runtime@^7.13.10":
version "7.13.10"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz#a1e40d22e2bf570c591c9c7e5ab42d6bf1e419e1"
integrity sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA==
"@babel/plugin-transform-runtime@^7.13.15":
version "7.13.15"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.15.tgz#2eddf585dd066b84102517e10a577f24f76a9cd7"
integrity sha512-d+ezl76gx6Jal08XngJUkXM4lFXK/5Ikl9Mh4HKDxSfGJXmZ9xG64XT2oivBzfxb/eQ62VfvoMkaCZUKJMVrBA==
dependencies:
"@babel/helper-module-imports" "^7.12.13"
"@babel/helper-module-imports" "^7.13.12"
"@babel/helper-plugin-utils" "^7.13.0"
babel-plugin-polyfill-corejs2 "^0.1.4"
babel-plugin-polyfill-corejs3 "^0.1.3"
babel-plugin-polyfill-regenerator "^0.1.2"
babel-plugin-polyfill-corejs2 "^0.2.0"
babel-plugin-polyfill-corejs3 "^0.2.0"
babel-plugin-polyfill-regenerator "^0.2.0"
semver "^6.3.0"
"@babel/runtime@^7.7.2":
@@ -305,21 +298,21 @@
"@babel/parser" "^7.12.13"
"@babel/types" "^7.12.13"
"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13":
version "7.13.13"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.13.tgz#39aa9c21aab69f74d948a486dd28a2dbdbf5114d"
integrity sha512-CblEcwmXKR6eP43oQGG++0QMTtCjAsa3frUuzHoiIJWpaIIi8dwMyEFUJoXRLxagGqCK+jALRwIO+o3R9p/uUg==
"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.13", "@babel/traverse@^7.13.15":
version "7.13.15"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.15.tgz#c38bf7679334ddd4028e8e1f7b3aa5019f0dada7"
integrity sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==
dependencies:
"@babel/code-frame" "^7.12.13"
"@babel/generator" "^7.13.9"
"@babel/helper-function-name" "^7.12.13"
"@babel/helper-split-export-declaration" "^7.12.13"
"@babel/parser" "^7.13.13"
"@babel/types" "^7.13.13"
"@babel/parser" "^7.13.15"
"@babel/types" "^7.13.14"
debug "^4.1.0"
globals "^11.1.0"
"@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.13", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
"@babel/types@^7.0.0", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.14", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
version "7.13.14"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d"
integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ==
@@ -891,10 +884,10 @@
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-4.0.1.tgz#bafd3d173974827ba0b733fcca7f1860cb71a9aa"
integrity sha512-k2hRcfcLRyPJjtYfJLzg404n7HZ6sUpAWAR/uNI8tf96NgatWOpw1ocdF+WFfx/trO1ivBh7ckynO1rn+xAw/Q==
"@octokit/openapi-types@^5.3.2":
version "5.3.2"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.2.tgz#b8ac43c5c3d00aef61a34cf744e315110c78deb4"
integrity sha512-NxF1yfYOUO92rCx3dwvA2onF30Vdlg7YUkMVXkeptqpzA3tRLplThhFleV/UKWFgh7rpKu1yYRbvNDUtzSopKA==
"@octokit/openapi-types@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-6.0.0.tgz#7da8d7d5a72d3282c1a3ff9f951c8133a707480d"
integrity sha512-CnDdK7ivHkBtJYzWzZm7gEkanA7gKH6a09Eguz7flHw//GacPJLmkHA3f3N++MJmlxD1Fl+mB7B32EEpSCwztQ==
"@octokit/plugin-paginate-rest@^2.6.2":
version "2.9.1"
@@ -908,12 +901,12 @@
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz#70a62be213e1edc04bb8897ee48c311482f9700d"
integrity sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==
"@octokit/plugin-rest-endpoint-methods@4.13.5":
version "4.13.5"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.5.tgz#ad76285b82fe05fbb4adf2774a9c887f3534a880"
integrity sha512-kYKcWkFm4Ldk8bZai2RVEP1z97k1C/Ay2FN9FNTBg7JIyKoiiJjks4OtT6cuKeZX39tqa+C3J9xeYc6G+6g8uQ==
"@octokit/plugin-rest-endpoint-methods@5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.0.tgz#cf2cdeb24ea829c31688216a5b165010b61f9a98"
integrity sha512-Jc7CLNUueIshXT+HWt6T+M0sySPjF32mSFQAK7UfAg8qGeRI6OM1GSBxDLwbXjkqy2NVdnqCedJcP1nC785JYg==
dependencies:
"@octokit/types" "^6.12.2"
"@octokit/types" "^6.13.0"
deprecation "^2.3.1"
"@octokit/request-error@^2.0.0":
@@ -953,15 +946,15 @@
once "^1.4.0"
universal-user-agent "^6.0.0"
"@octokit/rest@18.3.5":
version "18.3.5"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.3.5.tgz#a89903d46e0b4273bd3234674ec2777a651d68ab"
integrity sha512-ZPeRms3WhWxQBEvoIh0zzf8xdU2FX0Capa7+lTca8YHmRsO3QNJzf1H3PcuKKsfgp91/xVDRtX91sTe1kexlbw==
"@octokit/rest@18.5.2":
version "18.5.2"
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.5.2.tgz#0369e554b7076e3749005147be94c661c7a5a74b"
integrity sha512-Kz03XYfKS0yYdi61BkL9/aJ0pP2A/WK5vF/syhu9/kY30J8He3P68hv9GRpn8bULFx2K0A9MEErn4v3QEdbZcw==
dependencies:
"@octokit/core" "^3.2.3"
"@octokit/plugin-paginate-rest" "^2.6.2"
"@octokit/plugin-request-log" "^1.0.2"
"@octokit/plugin-rest-endpoint-methods" "4.13.5"
"@octokit/plugin-rest-endpoint-methods" "5.0.0"
"@octokit/types@^5.0.0", "@octokit/types@^5.0.1":
version "5.5.0"
@@ -978,12 +971,12 @@
"@octokit/openapi-types" "^4.0.0"
"@types/node" ">= 8"
"@octokit/types@^6.12.2":
version "6.12.2"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.12.2.tgz#5b44add079a478b8eb27d78cf384cc47e4411362"
integrity sha512-kCkiN8scbCmSq+gwdJV0iLgHc0O/GTPY1/cffo9kECu1MvatLPh9E+qFhfRIktKfHEA6ZYvv6S1B4Wnv3bi3pA==
"@octokit/types@^6.13.0":
version "6.13.0"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.13.0.tgz#779e5b7566c8dde68f2f6273861dd2f0409480d0"
integrity sha512-W2J9qlVIU11jMwKHUp5/rbVUeErqelCsO5vW5PKNb7wAXQVUz87Rc+imjlEvpvbH8yUb+KHmv8NEjVZdsdpyxA==
dependencies:
"@octokit/openapi-types" "^5.3.2"
"@octokit/openapi-types" "^6.0.0"
"@sindresorhus/is@^0.14.0":
version "0.14.0"
@@ -1218,10 +1211,10 @@
optionalDependencies:
prettier "^1.18.2"
"@vue/test-utils@^1.1.3":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.1.3.tgz#747f5683d8d4633c85a385fe2e02c1bb35bec153"
integrity sha512-BAY1Cwe9JpkJseimC295EW3YlAmgIJI9OPkg2FSP62+PHZooB0B+wceDi9TYyU57oqzL0yLbcP73JKFpKiLc9A==
"@vue/test-utils@^1.1.4":
version "1.1.4"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.1.4.tgz#a9acb32ea1fa4535b2e1ce5ca100bceb4fade2db"
integrity sha512-9BeL8IqGvJKy553lq/07rhYURQkpS/k+j19rJ/4eDpGJk7z872M0YrBWFhjS14yMKlvYVYOCfWnVIXyrAx0xNw==
dependencies:
dom-event-types "^1.0.0"
lodash "^4.17.15"
@@ -1835,29 +1828,29 @@ babel-plugin-jest-hoist@^26.6.2:
"@types/babel__core" "^7.0.0"
"@types/babel__traverse" "^7.0.6"
babel-plugin-polyfill-corejs2@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.5.tgz#8fc4779965311393594a1b9ad3adefab3860c8fe"
integrity sha512-5IzdFIjYWqlOFVr/hMYUpc+5fbfuvJTAISwIY58jhH++ZtawtNlcJnxAixlk8ahVwHCz1ipW/kpXYliEBp66wg==
babel-plugin-polyfill-corejs2@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.0.tgz#686775bf9a5aa757e10520903675e3889caeedc4"
integrity sha512-9bNwiR0dS881c5SHnzCmmGlMkJLl0OUZvxrxHo9w/iNoRuqaPjqlvBf4HrovXtQs/au5yKkpcdgfT1cC5PAZwg==
dependencies:
"@babel/compat-data" "^7.13.0"
"@babel/helper-define-polyfill-provider" "^0.1.2"
"@babel/compat-data" "^7.13.11"
"@babel/helper-define-polyfill-provider" "^0.2.0"
semver "^6.1.1"
babel-plugin-polyfill-corejs3@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.4.tgz#2ae290200e953bade30907b7a3bebcb696e6c59d"
integrity sha512-ysSzFn/qM8bvcDAn4mC7pKk85Y5dVaoa9h4u0mHxOEpDzabsseONhUpR7kHxpUinfj1bjU7mUZqD23rMZBoeSg==
babel-plugin-polyfill-corejs3@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.0.tgz#f4b4bb7b19329827df36ff56f6e6d367026cb7a2"
integrity sha512-zZyi7p3BCUyzNxLx8KV61zTINkkV65zVkDAFNZmrTCRVhjo1jAS+YLvDJ9Jgd/w2tsAviCwFHReYfxO3Iql8Yg==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.1.2"
core-js-compat "^3.8.1"
"@babel/helper-define-polyfill-provider" "^0.2.0"
core-js-compat "^3.9.1"
babel-plugin-polyfill-regenerator@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.3.tgz#350f857225fc640ae1ec78d1536afcbb457db841"
integrity sha512-hRjTJQiOYt/wBKEc+8V8p9OJ9799blAJcuKzn1JXh3pApHoWl1Emxh2BHc6MC7Qt6bbr3uDpNxaYQnATLIudEg==
babel-plugin-polyfill-regenerator@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.0.tgz#853f5f5716f4691d98c84f8069c7636ea8da7ab8"
integrity sha512-J7vKbCuD2Xi/eEHxquHN14bXAW9CXtecwuLrOIDJtcZzTaPzV1VdEfoUf9AzcRBMolKUQKM9/GVojeh0hFiqMg==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.1.2"
"@babel/helper-define-polyfill-provider" "^0.2.0"
babel-plugin-syntax-async-functions@^6.8.0:
version "6.13.0"
@@ -2403,10 +2396,10 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
buefy@^0.9.5:
version "0.9.5"
resolved "https://registry.yarnpkg.com/buefy/-/buefy-0.9.5.tgz#03e0e9d425f897dcbf6c0beb33d35a5f994b14c0"
integrity sha512-0LBY4XfvT/dgAg8AQBh2pdjTgDj5lpqBkmG4C2wWUAwZZ9UG75UxiH+wyct+b1DjkcuvQDzT4I3hlZvbduVdww==
buefy@^0.9.6:
version "0.9.6"
resolved "https://registry.yarnpkg.com/buefy/-/buefy-0.9.6.tgz#83c026c4a6f8fdcab80ded59181efc20873e3a99"
integrity sha512-qoYtbTf78xvC5fcRsuUKqUizJCAk2rg6LiAzON8X1G0GTsHkCWRWBHsJmU/jk1/6B+TQ10pSGkQgB+OLrREeXg==
dependencies:
bulma "0.9.2"
@@ -2525,10 +2518,10 @@ camelcase@^6.0.0, camelcase@^6.2.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001205:
version "1.0.30001205"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz#d79bf6a6fb13196b4bb46e5143a22ca0242e0ef8"
integrity sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==
caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30001181, caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001210:
version "1.0.30001210"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001210.tgz#7c12d029e93b725cc2fe44a5eaabd9b838250d33"
integrity sha512-avmGf0Jo00I8vB0I89J4Pba48kddasErV7slu7wrkyM5uY9gE5P+B+V3hjABv8Hp4YNG2nBqIUFUXlnqNteXEA==
capture-exit@^2.0.0:
version "2.0.0"
@@ -2580,10 +2573,10 @@ chardet@^0.7.0:
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
"chokidar@>=2.0.0 <4.0.0":
version "3.4.2"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d"
integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==
"chokidar@>=3.0.0 <4.0.0":
version "3.5.1"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
dependencies:
anymatch "~3.1.1"
braces "~3.0.2"
@@ -2591,9 +2584,9 @@ chardet@^0.7.0:
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
readdirp "~3.4.0"
readdirp "~3.5.0"
optionalDependencies:
fsevents "~2.1.2"
fsevents "~2.3.1"
chokidar@^2.1.8:
version "2.1.8"
@@ -2911,10 +2904,10 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
core-js-compat@^3.8.1:
version "3.9.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.0.tgz#29da39385f16b71e1915565aa0385c4e0963ad56"
integrity sha512-YK6fwFjCOKWwGnjFUR3c544YsnA/7DoLL0ysncuOJ4pwbriAtOpvM2bygdlcXbvQCQZ7bBU9CL4t7tGl7ETRpQ==
core-js-compat@^3.9.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.10.1.tgz#62183a3a77ceeffcc420d907a3e6fc67d9b27f1c"
integrity sha512-ZHQTdTPkqvw2CeHiZC970NNJcnwzT6YIueDMASKt+p3WbZsLXOcoD392SkcWhkC0wBBHhlfhqGKKsNCQUozYtg==
dependencies:
browserslist "^4.16.3"
semver "7.0.0"
@@ -2970,23 +2963,22 @@ css-color-names@1.0.1:
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67"
integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==
css-loader@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.0.tgz#a9ecda190500863673ce4434033710404efbff00"
integrity sha512-MfRo2MjEeLXMlUkeUwN71Vx5oc6EJnx5UQ4Yi9iUtYQvrPtwLUucYptz0hc6n++kdNcyF5olYBS4vPjJDAcLkw==
css-loader@^5.2.2:
version "5.2.2"
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.2.tgz#65f2c1482255f15847ecad6cbc515cae8a5b234e"
integrity sha512-IS722y7Lh2Yq+acMR74tdf3faMOLRP2RfLwS0VzSS7T98IHtacMWJLku3A0OBTFHB07zAa4nWBhA8gfxwQVWGQ==
dependencies:
camelcase "^6.2.0"
cssesc "^3.0.0"
icss-utils "^5.1.0"
loader-utils "^2.0.0"
postcss "^8.2.8"
postcss "^8.2.10"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0"
postcss-value-parser "^4.1.0"
schema-utils "^3.0.0"
semver "^7.3.4"
semver "^7.3.5"
css-select@^1.1.0:
version "1.2.0"
@@ -3051,10 +3043,10 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
date-fns@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
date-fns@^2.21.1:
version "2.21.1"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.21.1.tgz#679a4ccaa584c0706ea70b3fa92262ac3009d2b0"
integrity sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==
de-indent@^1.0.2:
version "1.0.2"
@@ -4018,11 +4010,16 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"
fsevents@^2.1.2, fsevents@~2.1.2:
fsevents@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e"
integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==
fsevents@~2.3.1:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -4164,10 +4161,10 @@ globals@^9.18.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==
globby@11.0.2:
version "11.0.2"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.2.tgz#1af538b766a3b540ebfb58a32b2e2d5897321d83"
integrity sha512-2ZThXDvvV8fYFRVIxnrMQBipZQDr7MxKAmQK1vujaj9/7eF0efG7BPUKJ7jP7G5SLF37xKDXvO4S/KKLj/Z0og==
globby@11.0.3:
version "11.0.3"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
@@ -5988,22 +5985,22 @@ micromatch@^4.0.2:
braces "^3.0.1"
picomatch "^2.0.5"
mime-db@1.46.0:
version "1.46.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==
mime-db@1.47.0:
version "1.47.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
"mime-db@>= 1.43.0 < 2":
version "1.45.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea"
integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==
mime-types@2.1.29, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.29"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2"
integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==
mime-types@2.1.30, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
version "2.1.30"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
dependencies:
mime-db "1.46.0"
mime-db "1.47.0"
mime@1.6.0, mime@^1.3.4:
version "1.6.0"
@@ -6037,10 +6034,10 @@ min-document@^2.19.0:
dependencies:
dom-walk "^0.1.0"
mini-css-extract-plugin@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.4.0.tgz#c8e571c4b6d63afa56c47260343adf623349c473"
integrity sha512-DyQr5DhXXARKZoc4kwvCvD95kh69dUupfuKOmBUqZ4kBTmRaRZcU32lYu3cLd6nEGXhQ1l7LzZ3F/CjItaY6VQ==
mini-css-extract-plugin@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.5.0.tgz#69bee3b273d2d4ee8649a2eb409514b7df744a27"
integrity sha512-SIbuLMv6jsk1FnLIU5OUG/+VMGUprEjM1+o2trOAx8i5KOKMrhyezb1dJ4Ugsykb8Jgq8/w5NEopy6escV9G7g==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
@@ -6874,10 +6871,10 @@ postcss@^7.0.14:
source-map "^0.6.1"
supports-color "^6.1.0"
postcss@^8.2.8, postcss@^8.2.9:
version "8.2.9"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.9.tgz#fd95ff37b5cee55c409b3fdd237296ab4096fba3"
integrity sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==
postcss@^8.2.10:
version "8.2.10"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b"
integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.22"
@@ -7132,10 +7129,10 @@ readdirp@^2.2.1:
micromatch "^3.1.10"
readable-stream "^2.0.2"
readdirp@~3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada"
integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==
readdirp@~3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
dependencies:
picomatch "^2.2.1"
@@ -7233,13 +7230,13 @@ relateurl@^0.2.7:
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
release-it@^14.5.0:
version "14.5.0"
resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.5.0.tgz#84ced16247b2ea92bc8e7b06c87daa60d5ce2b7e"
integrity sha512-3xwKx3B5i4TVMlCZsNXOCc/S3iviQmi64FJExsvMg5ZjlbBsEYF4qbPLVMq308i7MeDWhubiFHIb3XYuh8pt6Q==
release-it@^14.6.1:
version "14.6.1"
resolved "https://registry.yarnpkg.com/release-it/-/release-it-14.6.1.tgz#a04623312d67886b37b8a6d298844ee3e0c7150a"
integrity sha512-noBho2997G3yrm6YvdLJj4Ua2SCFOU7ajCqtvteI3DZtpM1IhiyXSgcn2Q5irq8lTNK0it4eiNq9TSrAWNYDkA==
dependencies:
"@iarna/toml" "2.2.5"
"@octokit/rest" "18.3.5"
"@octokit/rest" "18.5.2"
async-retry "1.3.1"
chalk "4.1.0"
cosmiconfig "7.0.0"
@@ -7249,17 +7246,17 @@ release-it@^14.5.0:
find-up "5.0.0"
form-data "4.0.0"
git-url-parse "11.4.4"
globby "11.0.2"
globby "11.0.3"
got "11.8.2"
import-cwd "3.0.0"
inquirer "8.0.0"
is-ci "3.0.0"
lodash "4.17.21"
mime-types "2.1.29"
mime-types "2.1.30"
ora "5.4.0"
os-name "4.0.0"
parse-json "5.2.0"
semver "7.3.4"
semver "7.3.5"
shelljs "0.8.4"
update-notifier "5.1.0"
url-join "4.0.1"
@@ -7530,12 +7527,12 @@ sass-loader@^11.0.1:
klona "^2.0.4"
neo-async "^2.6.2"
sass@^1.32.8:
version "1.32.8"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.8.tgz#f16a9abd8dc530add8834e506878a2808c037bdc"
integrity sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==
sass@^1.32.10:
version "1.32.10"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.10.tgz#d40da4e20031b450359ee1c7e69bc8cc89569241"
integrity sha512-Nx0pcWoonAkn7CRp0aE/hket1UP97GiR1IFw3kcjV3pnenhWgZEWUf0ZcfPOV2fK52fnOcK3JdC/YYZ9E47DTQ==
dependencies:
chokidar ">=2.0.0 <4.0.0"
chokidar ">=3.0.0 <4.0.0"
sax@>=0.6.0:
version "1.2.4"
@@ -7601,10 +7598,10 @@ semver@7.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
semver@7.3.4:
version "7.3.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
semver@7.3.5, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
@@ -7613,13 +7610,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
send@0.17.1:
version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
@@ -8808,10 +8798,10 @@ webpack-sources@^2.1.1:
source-list-map "^2.0.1"
source-map "^0.6.1"
webpack@^5.28.0:
version "5.28.0"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.28.0.tgz#0de8bcd706186b26da09d4d1e8cbd3e4025a7c2f"
integrity sha512-1xllYVmA4dIvRjHzwELgW4KjIU1fW4PEuEnjsylz7k7H5HgPOctIq7W1jrt3sKH9yG5d72//XWzsHhfoWvsQVg==
webpack@^5.33.2:
version "5.33.2"
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.33.2.tgz#c049717c9b038febf5a72fd2f53319ad59a8c1fc"
integrity sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg==
dependencies:
"@types/eslint-scope" "^3.7.0"
"@types/estree" "^0.0.46"