mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-21 22:30:46 +08:00
Compare commits
72
Commits
v0.1.5-beta
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac44c7e30b | ||
|
|
bf8a43fa87 | ||
|
|
284db90c16 | ||
|
|
223c14ab33 | ||
|
|
c53ec79ccd | ||
|
|
7dde3936d1 | ||
|
|
a4ffaa7350 | ||
|
|
eee9c7be70 | ||
|
|
b76757da33 | ||
|
|
b33de11ba8 | ||
|
|
1572171448 | ||
|
|
5e80591c85 | ||
|
|
48f55c5327 | ||
|
|
ca911b6aa6 | ||
|
|
cc472fe522 | ||
|
|
d98bd82c74 | ||
|
|
d0e9709603 | ||
|
|
d29b767d9c | ||
|
|
3fa2cae862 | ||
|
|
fe316220a1 | ||
|
|
4cd232f7e0 | ||
|
|
e5419c5cb1 | ||
|
|
04242e7d4a | ||
|
|
f6afe0fa12 | ||
|
|
30f9069e45 | ||
|
|
431781c798 | ||
|
|
f1b914fab9 | ||
|
|
c63a498034 | ||
|
|
82a20236e1 | ||
|
|
4e74171dc5 | ||
|
|
dfa5a65ba5 | ||
|
|
913e0f78db | ||
|
|
fc505b0733 | ||
|
|
06ae3d0555 | ||
|
|
58e07fe4aa | ||
|
|
d1f92000db | ||
|
|
6f921f6c97 | ||
|
|
94b46d32e4 | ||
|
|
07eb014d64 | ||
|
|
f9301ef0f4 | ||
|
|
8b30f83075 | ||
|
|
3242a49b27 | ||
|
|
b88bcd9113 | ||
|
|
f298901b17 | ||
|
|
71fc28cf22 | ||
|
|
ce8d76056f | ||
|
|
3ca242d086 | ||
|
|
9d7a5b4598 | ||
|
|
8e96962791 | ||
|
|
a59540d42d | ||
|
|
830dde3cec | ||
|
|
c308bbb6b0 | ||
|
|
c818b2a9db | ||
|
|
ee36205ac1 | ||
|
|
acbdbee26a | ||
|
|
9863821dbc | ||
|
|
206808e83a | ||
|
|
a248c6e39e | ||
|
|
5e2020efff | ||
|
|
c0bda707b7 | ||
|
|
ffc4318725 | ||
|
|
8023a9b021 | ||
|
|
56153510e1 | ||
|
|
be7343191d | ||
|
|
b1773ee5e9 | ||
|
|
18707cec47 | ||
|
|
993d3867ee | ||
|
|
d4d7435265 | ||
|
|
70f17453fd | ||
|
|
ef38cbc790 | ||
|
|
6205772a59 | ||
|
|
807186be61 |
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Environments**
|
||||
Your operating system, such as `Mac OS Catalina 10.15.7`.
|
||||
|
||||
**RevSuit Version**
|
||||
Versions of RevSuit with bugs.
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the new feature you expect to add**
|
||||
A clear and concise description.
|
||||
|
||||
**Why do you want to add this feature**
|
||||
A clear and concise description of why you need the feature, such as in what kind of usage scenarios it would be more convenient to have a certain feature.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
@@ -0,0 +1,11 @@
|
||||
### Describe the pull request
|
||||
|
||||
A clear and concise description of what the pull request is about, i.e. what problem should be fixed?
|
||||
|
||||
Link to the issue: <!-- paste the issue link here, or put "n/a" if not applicable -->
|
||||
|
||||
### Checklist
|
||||
|
||||
- [ ] I agree to follow the [Code of Conduct](https://go.dev/conduct) by submitting this pull request.
|
||||
- [ ] I have reviewed my own code.
|
||||
- [ ] All new and existing tests passed.
|
||||
@@ -21,8 +21,14 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/[email protected]
|
||||
- name: create dist directory
|
||||
run: mkdir frontend/dist && touch frontend/dist/revsuit
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
version: v1.37.0
|
||||
go-version: 1.19.x
|
||||
- name: Run golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: v1.49.0
|
||||
args: --timeout=30m
|
||||
|
||||
@@ -4,68 +4,40 @@ on:
|
||||
name: Build
|
||||
jobs:
|
||||
release-linux:
|
||||
name: release linux
|
||||
name: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.0'
|
||||
- name: compile
|
||||
env:
|
||||
CGO_ENABLE: 1
|
||||
CGO_LDFLAGS: -static
|
||||
run: |
|
||||
GOARCH="amd64" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
|
||||
GOARCH="386" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_i386" ./cmd/revsuit/revsuit.go
|
||||
GOARCH="arm" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_arm" ./cmd/revsuit/revsuit.go
|
||||
GOARCH="arm64" go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
|
||||
- name: Upload the artifacts
|
||||
uses: li4n0/upload-release-action@v2
|
||||
go-version: '^1.19.0'
|
||||
|
||||
- name: install nodejs
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: bin/*
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
release-darwin-amd64:
|
||||
name: release darwin/amd64
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.0'
|
||||
- name: compile
|
||||
env:
|
||||
CGO_ENABLE: 1
|
||||
run: |
|
||||
GOARCH="amd64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
||||
GOARCH="arm64" go build -v -ldflags="-s -w" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
|
||||
- name: Upload the artifacts
|
||||
uses: li4n0/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: bin/*
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
release-windows:
|
||||
name: release windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16.0'
|
||||
- name: compile
|
||||
env:
|
||||
CGO_ENABLE: 1
|
||||
CGO_LDFLAGS: -static
|
||||
run: |
|
||||
env GOARCH=amd64 go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_amd64.exe" ./cmd/revsuit/revsuit.go
|
||||
env GOARCH=386 go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_i386.exe" ./cmd/revsuit/revsuit.go
|
||||
env GOARCH=arm go build -v -ldflags="-s -w -extldflags=-static" -trimpath -o "bin/revsuit_windows_arm.exe" ./cmd/revsuit/revsuit.go
|
||||
node-version: '12'
|
||||
|
||||
- name: install yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: build frontend
|
||||
run: cd frontend && yarn install && yarn build
|
||||
|
||||
- name: get the version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
|
||||
|
||||
- name: compile linux amd64
|
||||
run: CGO_ENABLE=0 GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
|
||||
- name: compile linux arm64
|
||||
run: CGO_ENABLE=0 GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
|
||||
- name: compile darwin amd64
|
||||
run: CGO_ENABLE=0 GOOS="darwin" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
||||
- name: compile darwin arm64
|
||||
run: CGO_ENABLE=0 GOOS="darwin" GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
|
||||
- name: compile windows amd64
|
||||
run: CGO_ENABLE=0 GOOS="windows" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}' " -trimpath -o "bin/revsuit_windows_amd64.exe" ./cmd/revsuit/revsuit.go
|
||||
|
||||
- name: Upload the artifacts
|
||||
uses: li4n0/upload-release-action@v2
|
||||
with:
|
||||
|
||||
+8
-2
@@ -11,7 +11,7 @@ GeoLite2-City.mmdb
|
||||
config.yaml*
|
||||
|
||||
# binary
|
||||
revsuit
|
||||
/revsuit
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
@@ -23,6 +23,12 @@ revsuit
|
||||
*.sw?
|
||||
|
||||
## node
|
||||
package.json
|
||||
/package.json
|
||||
package-lock.json
|
||||
node_modules/
|
||||
|
||||
## frontend dist
|
||||
dist/
|
||||
|
||||
## received files
|
||||
revsuit-files
|
||||
|
||||
@@ -15,18 +15,14 @@ linters-settings:
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
- nakedret
|
||||
- gofmt
|
||||
- rowserrcheck
|
||||
- unconvert
|
||||
- goimports
|
||||
|
||||
+122
@@ -2,6 +2,128 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.7.1](https://github.com/Li4n0/revsuit/compare/v0.7.0...v0.7.1) (2023-06-01)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix the error that the maximum length of http rule response body is 191 when using mysql ([bf8a43f](https://github.com/Li4n0/revsuit/commit/bf8a43fa875327c3191499a214c420bfa78334d0))
|
||||
|
||||
## [0.7.0](https://github.com/Li4n0/revsuit/compare/v0.6.0...v0.7.0) (2023-05-23)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add `value` field to the dns log ([#67](https://github.com/Li4n0/revsuit/issues/67)) ([223c14a](https://github.com/Li4n0/revsuit/commit/223c14ab33757e06b0d8177091982582e08e70c4))
|
||||
|
||||
## [0.6.0](https://github.com/Li4n0/revsuit/compare/v0.5.2...v0.6.0) (2023-03-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support for using `Flag-Filter` request headers to filter the flags that the client expects to receive ([#64](https://github.com/Li4n0/revsuit/issues/64)) ([b33de11](https://github.com/Li4n0/revsuit/commit/b33de11ba8f126b03a45ad15cae69331ad59b865)) (Thanks to @whwlsfb)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix static resource loading failure after modifying `admin_path_prefix` ([b76757d](https://github.com/Li4n0/revsuit/commit/b76757da331b56f240ec2a0c69d479f3184bc4c2)), closes [#63](https://github.com/Li4n0/revsuit/issues/63)
|
||||
|
||||
### [0.5.2](https://github.com/Li4n0/revsuit/compare/v0.5.1...v0.5.2) (2022-11-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix bug that the files associated with records still exist after deleting mysql and ftp records ([5e80591](https://github.com/Li4n0/revsuit/commit/5e80591c856a63c851ba5e17812af89373d76cf5))
|
||||
* fix panic when update config ([#62](https://github.com/Li4n0/revsuit/issues/62)) ([48f55c5](https://github.com/Li4n0/revsuit/commit/48f55c53273fcea579c9fdfaf2939c90df3588b1))
|
||||
|
||||
### [0.5.1](https://github.com/Li4n0/revsuit/compare/v0.5.0...v0.5.1) (2022-09-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix the bug that authentication always fails after token change ([#59](https://github.com/Li4n0/revsuit/issues/59)) ([3fa2cae](https://github.com/Li4n0/revsuit/commit/3fa2cae86260d39fa2ffd43d59b2754327f6169a))
|
||||
* fix the error of `database is locked` when use sqlite ([#60](https://github.com/Li4n0/revsuit/issues/60)) ([d29b767](https://github.com/Li4n0/revsuit/commit/d29b767d9cb2b70f365d0830c4bbeaae09524a5a))
|
||||
|
||||
## [0.5.0](https://github.com/Li4n0/revsuit/compare/v0.4.0...v0.5.0) (2022-01-16)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **build:** replace sqlite driver with which does not depend cgo ([#52](https://github.com/Li4n0/revsuit/issues/52)) ([82a2023](https://github.com/Li4n0/revsuit/commit/82a20236e1b1a092277b645554a38513e3bb4087))
|
||||
* **dns:** support use multiple root domains ([#51](https://github.com/Li4n0/revsuit/issues/51)) ([913e0f7](https://github.com/Li4n0/revsuit/commit/913e0f78db380cb1beeb88b57dc30f47e7c26c1c))
|
||||
* **ldap:** add ldap protocol support ([#50](https://github.com/Li4n0/revsuit/issues/50)) ([fc505b0](https://github.com/Li4n0/revsuit/commit/fc505b0733a8375d29b910aa897c6e0b642ab34b))
|
||||
* support auto check upgrade ([#53](https://github.com/Li4n0/revsuit/issues/53)) ([f6afe0f](https://github.com/Li4n0/revsuit/commit/f6afe0fa12188f17b74548129035f7b89a149660))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **settings:** fix the bug of update rmi & mysql addr settings not working ([#49](https://github.com/Li4n0/revsuit/issues/49)) ([06ae3d0](https://github.com/Li4n0/revsuit/commit/06ae3d0555eff3bf2d6a53b2c405d1dd50beea87))
|
||||
|
||||
## [0.4.0](https://github.com/Li4n0/revsuit/compare/v0.3.0...v0.4.0) (2021-12-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **database:** support postgres ([#43](https://github.com/Li4n0/revsuit/issues/43)) ([8b30f83](https://github.com/Li4n0/revsuit/commit/8b30f83075bab3f62546793c471b74075745d8d0))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **rmi:** fix the problem that rmi has multiple rules matching in one record ([6f921f6](https://github.com/Li4n0/revsuit/commit/6f921f6c97f39638c73de13d87879514485125ef))
|
||||
* **server:** fix auth failure when complex characters in token ([#42](https://github.com/Li4n0/revsuit/issues/42)) ([3242a49](https://github.com/Li4n0/revsuit/commit/3242a49b2731392125e5c22375549586495ee6fc))
|
||||
|
||||
## [0.3.0](https://github.com/Li4n0/revsuit/compare/v0.2.1...v0.3.0) (2021-12-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **database:** add mysql support ([#39](https://github.com/Li4n0/revsuit/issues/39)) ([9d7a5b4](https://github.com/Li4n0/revsuit/commit/9d7a5b45984bb3fee187146b0f27e77d6ec0ea0a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cli:** fix typos ([#41](https://github.com/Li4n0/revsuit/issues/41)) ([8e96962](https://github.com/Li4n0/revsuit/commit/8e969627917fda9ce220283eb34599b781f03ae3))
|
||||
* **database:** fix the error when load package ([3ca242d](https://github.com/Li4n0/revsuit/commit/3ca242d0866f5f10aade3557d80b8252be7ef938))
|
||||
* **mysql/record:** fix the bug when searching mysql record with username as keyword ([ce8d760](https://github.com/Li4n0/revsuit/commit/ce8d76056faec45d3e68164b3802ceaaec0468b9))
|
||||
* **pkg:** fix the conflict between rank field and built-in function ([#38](https://github.com/Li4n0/revsuit/issues/38)) ([a59540d](https://github.com/Li4n0/revsuit/commit/a59540d42ddf820e445a8395c2995fa89fc14323))
|
||||
|
||||
### [0.2.1](https://github.com/Li4n0/revsuit/compare/v0.2.0...v0.2.1) (2021-07-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **rule:** add `flag` as a built-in template variable ([ee36205](https://github.com/Li4n0/revsuit/commit/ee36205ac160a75d23dbb244c72f3bb2d185ab80))
|
||||
|
||||
## [0.2.0](https://github.com/Li4n0/revsuit/compare/v0.1.7...v0.2.0) (2021-07-22)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support deleting logs based on filtering results ([#35](https://github.com/Li4n0/revsuit/issues/35)) ([9863821](https://github.com/Li4n0/revsuit/commit/9863821dbc351734569b7ec1eda2b6712bd02bb0))
|
||||
|
||||
### [0.1.7](https://github.com/Li4n0/revsuit/compare/v0.1.6...v0.1.7) (2021-07-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **http:** fix the bug that http record url search does not work ([ffc4318](https://github.com/Li4n0/revsuit/commit/ffc4318725017c7eda7ec11ca67d5de16ad1e8a8))
|
||||
* **mysql:** fix the bug that crashes when mysql port conflicts ([c0bda70](https://github.com/Li4n0/revsuit/commit/c0bda707b750b7858fdd4efc414b726ee37e71da))
|
||||
|
||||
### [0.1.6](https://github.com/Li4n0/revsuit/compare/v0.1.5...v0.1.6) (2021-06-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cli:** fix the bug that the prompt may not be output when generating config file ([5615351](https://github.com/Li4n0/revsuit/commit/56153510e11783c08843cbb8b0f827d5f8567842))
|
||||
* **ipinfo:** fix a potential panic when downloading ip location database ([#33](https://github.com/Li4n0/revsuit/issues/33)) ([b1773ee](https://github.com/Li4n0/revsuit/commit/b1773ee5e9ebd8c8be72f315981268992c08b3f1))
|
||||
|
||||
### [0.1.5](https://github.com/Li4n0/revsuit/compare/v0.1.5-beta...v0.1.5) (2021-06-22 公开该项目以庆祝毕业,愿工作多年后的我,归来时仍是少年)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **notice:** fix the buf of notice with null record field ([#31](https://github.com/Li4n0/revsuit/issues/31)) ([ef38cbc](https://github.com/Li4n0/revsuit/commit/ef38cbc790f69716a335167321e1c7c8bdee2e41))
|
||||
|
||||
### [0.1.5-beta](https://github.com/Li4n0/revsuit/compare/v0.1.4-beta-fix-1...v0.1.5-beta) (2021-06-13)
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
## Configuration file description
|
||||
|
||||
RevSuit will generate a profile template the first time it is run, and you can edit its contents to implement some customization requirements.
|
||||
```yaml
|
||||
version: 1.5
|
||||
addr: :10000 # Address of the HTTP service will listen
|
||||
token: # Authentication Token, both the admin page and the client need to be authenticated by this Token
|
||||
domains: [] # The domain names used by the platform
|
||||
external_ip: # The external IP of the platform, you need to make sure that the target you want to test can access the platform through this IP
|
||||
admin_path_prefix: "/revsuit" # The http path prefix for the admin page, the page will be located at: /admin_path_prefix/admin
|
||||
# Database connection information, support using MySQL, Postgres, Sqlite3
|
||||
database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||||
#database: revsuit.db # The use of sqlite databases on some systems may cause `SQLITE BUSY` problems in concurrent scenarios, so it is not recommended for use in a formal environment
|
||||
|
||||
log_level: info # Output log levels, divided into: debug, info, warning, error, fatal
|
||||
check_upgrade: true # Whether to automatically check for updates
|
||||
|
||||
ip_location_database: # IP database related configuration
|
||||
database: "qqwry" # qqwry or geoip.
|
||||
geo_license_key: "" # Mandatory field, if you choose to use GeoIP.
|
||||
|
||||
http: # HTTP receive connection related configuration
|
||||
ip_header: # Specify the source IP via the HTTP Header, which is usually required when there is a predecessor reverse proxy
|
||||
dns: # DNS receive connection related configuration
|
||||
enable: true
|
||||
addr: :53 # Address of the DNS service will listen
|
||||
rmi: # RMI receive connection related configuration
|
||||
enable: true
|
||||
addr: :1099 # Address of the RMI service will listen
|
||||
ldap:
|
||||
enable: true
|
||||
addr: :1389 # Address of the Ldap service will listen
|
||||
mysql: # MySQL receive connection related configuration
|
||||
enable: true
|
||||
addr: :3306 # Address of the MySQL service will listen
|
||||
version_string: 10.4.13-MariaDB-log # The version of the MySQL service in disguise
|
||||
ftp: # FTP receive connection related configuration
|
||||
enable: true
|
||||
addr: :21 # Address of the FTP service will listen
|
||||
pasv_port: 2020 # FTP passive mode port listening address
|
||||
notice:
|
||||
dingtalk: https://oapi.dingtalk.com/robot/send?access_token={token} # Webhook of DingTalk Bot
|
||||
lark: https://open.feishu.cn/open-apis/bot/v2/hook/{token} # Webhook of Lark Bot
|
||||
weixin: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key} # Webhook of Weixin Bot
|
||||
slack: https://hooks.slack.com/services/{id}/{token} # Webhook of Slack Bot
|
||||
```
|
||||
@@ -0,0 +1,47 @@
|
||||
## 配置文件说明
|
||||
|
||||
```yaml
|
||||
version: 1.5
|
||||
addr: :10000 # HTTP 服务监听的地址
|
||||
token: # 鉴权Token,管理页面和客户端都需要通过该 Token 进行鉴权
|
||||
domains: [] # 反连平台绑定的域名
|
||||
external_ip: # 反连平台的外部IP,需要确保你想测试的目标能通过该 IP 访问到平台
|
||||
admin_path_prefix: "/revsuit" # 管理页面的 http path 前缀,管理页面将位于:/admin_path_prefix/admin
|
||||
# 数据库连接信息 支持MySQL、Postgres、SQLite3
|
||||
database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
||||
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||||
#database: revsuit.db # 在部分系统上使用 sqlite 数据库时,在并发场景下可能会出现 `SQLITE BUSY` 的问题,因此不推荐在正式环境中使用该类型数据库
|
||||
|
||||
log_level: info # 输出日志的级别,分为:debug、info、warning、error、fatal
|
||||
check_upgrade: false # 是否自动检查更新
|
||||
|
||||
ip_location_database: # IP 数据库相关配置
|
||||
database: "qqwry" # qqwry 或者 geoip.
|
||||
geo_license_key: "" # 如果你使用 GeoIP 则该字段为必填
|
||||
|
||||
http: # HTTP 反连相关配置
|
||||
ip_header: # 通过 HTTP 请求头获取来源IP,通常在有前置反向代理时需要配置
|
||||
dns: # DNS 反连相关配置
|
||||
enable: true
|
||||
addr: :53 # DNS 服务监听的地址
|
||||
rmi: # RMI 反连相关配置
|
||||
enable: true
|
||||
addr: :1099 # RMI 服务监听的地址
|
||||
ldap:
|
||||
enable: true
|
||||
addr: :1389 # Ldap 服务监听的地址
|
||||
mysql: # MySQL 反连相关配置
|
||||
enable: true
|
||||
addr: :3306 # MySQL 服务监听的地址
|
||||
version_string: 10.4.13-MariaDB-log # 伪装MySQL服务的版本
|
||||
ftp: # FTP 反连相关配置
|
||||
enable: true
|
||||
addr: :21 # FTP 服务监听的地址
|
||||
pasv_port: 2020 # FTP被动模式端口监听的地址
|
||||
notice:
|
||||
dingtalk: https://oapi.dingtalk.com/robot/send?access_token={token} # 钉钉机器人webhook地址
|
||||
lark: https://open.feishu.cn/open-apis/bot/v2/hook/{token} # 飞书机器人webhook地址
|
||||
weixin: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={key} # 企业微信机器人webhook地址
|
||||
slack: https://hooks.slack.com/services/{id}/{token} # slack机器人webhook地址
|
||||
|
||||
```
|
||||
@@ -1,19 +1,21 @@
|
||||
# RevSuit - A Flexible and Powerful Reverse Connection Platform
|
||||
|
||||
English |[简体中文](./README.zh-CN.md)
|
||||
|
||||
## Overview
|
||||
|
||||
RevSuit is a flexible and powerful reverse connection platform designed for receiving connection from target host in
|
||||
penetration. It currently supports HTTP, DNS, RMI, MySQL and FTP protocols.
|
||||
penetration. It currently supports HTTP, DNS, RMI, LDAP, MySQL and FTP protocols.
|
||||
|
||||
Flexible:
|
||||
|
||||
1. Revsuit can set flexible rules to capture different connections.
|
||||
1. RevSuit can set flexible rules to capture different connections.
|
||||
2. Deploy and run via binaries without worrying about nasty dependency errors.
|
||||
|
||||
Powerful:
|
||||
|
||||
1. Revsuit allows users to customize the response for different connections through rules and supports dynamic response
|
||||
generation using template variables.
|
||||
1. Allows to customize the response for different connections through rules and supports dynamic response generation
|
||||
using template variables.
|
||||
2. Support a variety of protocols, and support the in-depth utilization of some protocols, such as DNS rebinding, MySQL
|
||||
Load Local Data, JDBC Deserialize Exploit, FTP Passive Mode SSRF, etc.
|
||||
3. Native support for use with scanners.
|
||||
@@ -22,14 +24,22 @@ Powerful:
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Preparation
|
||||
### Installation and Configuration
|
||||
|
||||
Download the latest release firstly.
|
||||
Download the latest release directly or build by following steps:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Li4n0/revsuit.git
|
||||
cd revsuit/frontend && yarn install && yarn build
|
||||
cd ../ && go build ./cmd/revsuit/revsuit.go
|
||||
```
|
||||
|
||||
RevSuit will generate default configuration file on first run. Modify the configuration file according to your needs,
|
||||
then re-run.
|
||||
then re-run. A detailed description of the configuration file can be found at: [Configuration Notes](./CONFIG.md)
|
||||
|
||||
In order to confirm the IP location, you need to use the IP location database. `QQwry` is used as the data source by
|
||||
### Run
|
||||
|
||||
In order to confirm the IP location, it needs to use the IP location database. `QQwry` is used as the data source by
|
||||
default, you can also modify the configuration to use `GeoIP`. If the selected database is not available in the current
|
||||
directory or the database is updated for more than a week, RevSuit will automatically download the latest database. If
|
||||
the download fails, the `IpArea` field will always be null.
|
||||
@@ -65,8 +75,8 @@ A few notes are as follows:
|
||||
2. `FlagFormat` uses regular expression syntax, and for different protocols, the fields matched by flagFormat are
|
||||
different, you can check the corresponding hints to get details when creating rules.
|
||||
3. Rules with high rank will take effect first.
|
||||
4. For different protocol rules, you can make different custom configurations, and for some protocols, template
|
||||
variables can be used.
|
||||
4. For different protocol rules, you can make different custom responses, and for some protocols, template variables can
|
||||
be used.
|
||||
5. You can set the named grouping of regular expressions in `flagFormat`, and the result of the matching grouping will
|
||||
also be used as a template variable.
|
||||
|
||||
@@ -129,7 +139,7 @@ RevSuit was split from my scanner project, so its native support works with scan
|
||||
|
||||
From RevSuit's perspective, we call a scanner a client.
|
||||
|
||||
#### Create Connection
|
||||
#### Establish connection
|
||||
|
||||
RevSuit
|
||||
uses [HTTP Server-sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
|
||||
@@ -145,8 +155,13 @@ example.
|
||||
|
||||
#### Multi-client
|
||||
|
||||
As shown above, RevSuit supports multiple clients, and each client in the connected state receives a push of `flag`, so
|
||||
distributed scanning can be supported.
|
||||
As shown above, RevSuit supports multiple clients, and each client **in the connected state** receives a push of `flag`,
|
||||
so distributed scanning can be supported.
|
||||
|
||||
If you don't want every client to receive all `flag` pushes, you can use the `Flag-Filter` request header when creating an sse connection to set the format(regular expressions) of the `flag` you want that client to receive:
|
||||
|
||||

|
||||
|
||||
|
||||
#### Temporary storage queue
|
||||
|
||||
@@ -156,15 +171,15 @@ helpful for discovering delay-triggered vulnerabilities.)
|
||||
|
||||
#### Use flagGroup
|
||||
|
||||
`FlagGroup` is the content matched by the anonymous group in the `flagFormat` field of the rule. The platform will check
|
||||
the content matched in the grouping,and the flag is only pushed to the client when then content(`flagGroup`) captured
|
||||
for the first time.
|
||||
|
||||
In a real-world vulnerability scanning scenario, you may send a large number of different payloads for a single
|
||||
vulnerability point, and they may all be valid, which can result in the backlink platform receiving many requests, yet
|
||||
they are caused by the same vulnerability. If you don't want the client to receive so many `flags` for the same
|
||||
vulnerability, you can take advantage of the `flagGroup` feature of rule's flagFormat.
|
||||
|
||||
`FlagGroup` is the content matched by the anonymous group in the `flagFormat` field of the rule. The platform will check
|
||||
the content matched in the grouping,and the flag is only pushed to the client when then content(`flagGroup`) captured
|
||||
for the first time.
|
||||
|
||||
For example, SSRF scanning.
|
||||
|
||||
Firstly create a rule like the following:
|
||||
@@ -183,23 +198,22 @@ http:
|
||||
|
||||
Suppose our target is `https://www.testvuln.com?url=api.com&p=useless`, and for SSRF we have 5 payloads. The final
|
||||
request sent by the scanner may
|
||||
be `['https://www.testvuln.com?url=http://revsuit.com/ssrfa98oni1&p=useless, ... ,'https://www.testvuln.com?url=//revsuit.com/ssrfa98oni5&p=useless`']
|
||||
be `['https://www.testvuln.com?url=http://revsuit.com/ssrfa98oni1&p=useless','https://www.testvuln.com?url=http://revsuit.com/ssrfa98oni2&p=useless', ... ,'https://www.testvuln.com?url=//revsuit.com/ssrfa98oni5&p=useless`']
|
||||
. They may all attack successfully.
|
||||
|
||||
However, because anonymous grouping is used in the rule's `flagFormat`, The platform will query the
|
||||
connected `flagGroup`, in this case `ssrfa98oni`, and push `flag` to the client only at its first appearance, so the
|
||||
client will only receive one flag:`ssrfa98oni1`. But this is enough, because it already proves that the `url` parameter
|
||||
of the target is vulnerable.
|
||||
client will only receive one flag:`ssrfa98oni1`. It already proves that the `url` parameter of the target is vulnerable.
|
||||
|
||||
### Multi-module collocation
|
||||
|
||||
In actual penetration testing scenarios, certain tasks can be done easily and quickly by combining and matching various
|
||||
modules of RevSuit. The following is an example of a blind XXE scenario, showing how to use RevSuit's HTTP and FTP
|
||||
modules of RevSuit. The following is an example of a blind XXE in Java Web, showing how to use RevSuit's HTTP and FTP
|
||||
modules, combined with template variables, to quickly complete a port scan.
|
||||
|
||||
First use create an HTTP rule to return evil.dtd, customize the response to the contents of dtd so that it goes to
|
||||
connect to RevSuit's FTP service, and use template variables to pass the Host and Port to be scanned to FTP via FTP's
|
||||
user and password.
|
||||
First create an HTTP rule to return evil.dtd, customize the response to the contents of dtd so that it goes to connect
|
||||
to RevSuit's FTP service, and use template variables to pass the Host and Port to be scanned to FTP via FTP's user and
|
||||
password.
|
||||
|
||||

|
||||
|
||||
@@ -225,16 +239,19 @@ and 8080 are open.
|
||||
|
||||
A more detailed wiki is being prepared, you can explore by yourself before it.
|
||||
|
||||
## Advice and Communication
|
||||
## Feedback, Suggestions and Communication
|
||||
|
||||
Submit an issue or contact me through Weixin: `Li4n06`
|
||||
Submit an issue or contact me through Weixin: `TGk0bjA2Cg==`
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
### Reference
|
||||
|
||||
This project draws on the code of the following outstanding projects:
|
||||
|
||||
* [https://github.com/rmb122/rogue_mysql_server](https://github.com/rmb122/rogue_mysql_server)
|
||||
* [https://github.com/256dpi/newdns](https://github.com/256dpi/newdns)
|
||||
* [https://github.com/EmYiQing/JNDIScan](https://github.com/EmYiQing/JNDIScan)
|
||||
|
||||
### Specifically
|
||||
|
||||
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
# RevSuit - A Flexible and Powerful Reverse Connection Platform
|
||||
|
||||
简体中文 |[English](./README.md)
|
||||
|
||||
## 简介
|
||||
|
||||
RevSuit 是一款灵活并且强大的反连平台。目前支持 HTTP、DNS、RMI、LDAP、MySQL 和 FTP 协议。
|
||||
|
||||
灵活:
|
||||
|
||||
1. 通过灵活的规则来捕获连接
|
||||
2. 通过二进制文件部署和运行而无需担心讨厌的依赖错误
|
||||
|
||||
强大:
|
||||
|
||||
1. 可以通过规则,为不同类型的连接自定义响应,并且可以使用模板变量实现动态响应。
|
||||
2. 支持的协议数量相对较多,并且支持其中的部分协议的进一步利用,如 DNS重绑定、MySQL客户端文件读取和 JDBC 反序列化、FTP 被动模式 SSRF 等
|
||||
3. 原生支持扫描器
|
||||
4. 支持发送通知到流行的办公软件
|
||||
5. 其它有趣或贴心的功能
|
||||
|
||||
## 基础使用
|
||||
|
||||
### 安装及配置
|
||||
|
||||
在 Releases 里下载最新版本的 RevSuit,或者通过以下命令自行编译:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Li4n0/revsuit.git
|
||||
cd revsuit/frontend && yarn install && yarn build
|
||||
cd ../ && go build ./cmd/revsuit/revsuit.go
|
||||
```
|
||||
|
||||
RevSuit首次运行将会在当前目录生成配置文件,您可以根据需要自定义其中的某些内容。配置文件的详细说明可见:[配置说明](./CONFIG.zh-CN.md)
|
||||
|
||||
### 运行
|
||||
为了确认连接 IP 的归属地,RevSuit 需要依赖 IP 归属地数据库。默认情况下使用纯真 IP 库,你也可以在配置文件中指定使用 GeoIP。如果当前目录下没有被选中的IP数据库文件,或者IP数据库文件更新的时间大于一周,RevSuit
|
||||
将会自动下载最新版的数据库文件到本地。如果下载失败,连接记录的`IpArea`字段将始终为空。
|
||||
|
||||
```bash
|
||||
$ ./revsuit
|
||||
2021/05/16 22:55:10 [ INFO] Downloading qqwry.dat...
|
||||
|
||||
____ _____ _ __
|
||||
/ __ \___ _ __/ ___/__ __(_) /_
|
||||
/ /_/ / _ \ | / /\__ \/ / / / / __/
|
||||
/ _, _/ __/ |/ /___/ / /_/ / / /_
|
||||
/_/ |_|\___/|___//____/\__,_/_/\__/
|
||||
vBeta0.1
|
||||
https://revsuit.pro
|
||||
2021/05/16 22:55:22 [ INFO] Starting HTTP Server at :80, token:your_token
|
||||
2021/05/16 22:55:22 [ INFO] Start to listen FTP PASV port at :2020, PasvIP is 10.9.8.7
|
||||
2021/05/16 22:55:22 [ INFO] Starting FTP Server at :21
|
||||
2021/05/16 22:55:22 [ INFO] Starting MySQL Server at :3306
|
||||
2021/05/16 22:55:22 [ INFO] Starting RMI Server at :1099
|
||||
2021/05/16 22:55:22 [ INFO] Starting DNS Server at :53
|
||||
```
|
||||
|
||||
在启动之后,你可以通过访问HTTP Server的`/revsuit/admin/`路径,并输入 token 来进入控制面板。
|
||||
|
||||
### 创建规则与接收连接
|
||||
|
||||
这里以创建一个HTTP规则作为例子:
|
||||
|
||||
一些需要注意的内容如下:
|
||||
|
||||
1. 规则的 `name` 和 `flagFormat` 字段是唯一的。
|
||||
2. `flagFormat` 使用正则表达式语法。对于不同的协议,其匹配的字段也是不同的。你可以在创建规则的时候查看对应的帮助信息来获知该协议的哪个字段是会被匹配的。
|
||||
3. `rank` 决定了规则的优先级,如果一个请求同时满足多条规则,只有 `rank` 值最大的那条规则会生效。
|
||||
4. 对于不同的协议,你可以设置不同的响应,部分协议可以使用模板变量来动态生成响应。
|
||||
5. 你可以在 `flagFormat` 中使用正则表达式中的命名分组,命名分组匹配的结果将会成为自定义的模板变量。
|
||||
|
||||
如下图所示,我们创建一个名为 `test_create_rule` 的HTTP协议的规则,其中使用了内置的模板变量和自定义的模板变量:
|
||||
|
||||

|
||||
|
||||
然后发送一个满足这条规则的请求来进行测试,可以看到响应的内容中各个模板变量都获取到了对应的值:
|
||||
|
||||

|
||||
|
||||
这条请求同时会被记录在平台:
|
||||
|
||||

|
||||
|
||||
### 通知
|
||||
|
||||
通过配置 Webhook 地址并打开对应规则的 `Notice` 开关,你可以通过办公软件接收新连接的通知。目前支持 钉钉、企业微信、飞书 和 slack。(计划会后续支持Discord 和 Telegram)
|
||||
|
||||
### 导入/导出规则
|
||||
|
||||
如果你想要迁移平台或者清除数据,重新创建规则可能是一件麻烦事。因此 RevSuit 支持导入和导出规则。
|
||||
|
||||
该功能位于 `Settings>RULES` 选项卡,如下所示,规则将会被以 yaml 的格式进行导入和导出:
|
||||
|
||||
```yaml
|
||||
http:
|
||||
- name: test_create_rule
|
||||
flag_format: (?P<what>\w+)\?
|
||||
rank: 0
|
||||
push_to_client: false
|
||||
notice: false
|
||||
response_status_code: "302"
|
||||
response_headers:
|
||||
Location: ${query.url}
|
||||
response_body: ${header.say} ${what}
|
||||
- name: other_rule
|
||||
flag_format: other
|
||||
rank: 1
|
||||
push_to_client: false
|
||||
notice: true
|
||||
response_status_code: "200"
|
||||
response_headers: { }
|
||||
response_body: Hello Revsuit!
|
||||
dns:
|
||||
... ...
|
||||
```
|
||||
|
||||
## 高级功能
|
||||
|
||||
### 与扫描器适配
|
||||
|
||||
RevSuit 拆分自我的扫描器项目,因此它原生支持搭配扫描器使用。
|
||||
|
||||
从 RevSuit 的视角,我们称扫描器为客户端。
|
||||
|
||||
#### 建立通信管道
|
||||
|
||||
RevSuit
|
||||
使用 [HTTP Server-sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)
|
||||
(SSE) 与客户端建立一条单向通信管道。
|
||||
|
||||
通信管道的API为 `/revsuit/api/events?message`。客户端只需携带 `Token: your token` 请求头,然后请求这个 API 来建立通信管道。这样当 RevSuit
|
||||
捕获新连接的时候,匹配到的 `flag` 就会通过这条管道传递给客户端。
|
||||
|
||||

|
||||
|
||||
这里是一个使用 Go 语言的 sse 库编写客户端的[简单例子](https://gist.github.com/Li4n0/21aa0bec2d626114a729ca2677efb05a) 。
|
||||
|
||||
#### 多客户端
|
||||
|
||||
如上一节的图片里所展示的,RevSuit 支持多个客户端,每个在**连接状态**的客户端都会接收到 `flag` 的推送,因此分布式扫描也是支持的。
|
||||
|
||||
如果你不希望每个客户端都收到全部的 `flag` 推送,你可以在创建 sse 连接时,使用 `Flag-Filter` 请求头设置希望该客户端接受的 `flag` 的格式(支持正则表达式),例如:
|
||||
|
||||

|
||||
|
||||
|
||||
#### 暂存队列
|
||||
|
||||
当没有客户端连接的时候,RevSuit 会把 `flag` 暂时存储到队列里,当有客户端连接的时候再进行推送。因此你不必担心因为客户端与 RevSuit 断开连接就错过漏洞。(这对发现延时触发的漏洞尤为有帮助)
|
||||
|
||||
#### 使用flagGroup
|
||||
|
||||
在真实的漏洞扫描情景中,对于一个漏洞点,往往会发送许多不同的 payload,它们可能全部是有效 payload,这会导致 RevSuit
|
||||
收到很多个连接,然而这些连接背后的漏洞其实是同一个。如果你不想客户端收到代表同一个漏洞的 `flag`
|
||||
,你可以使用 `flagGroup`。
|
||||
|
||||
`flagGroup` 是被规则中的 `flagFormat` 中的匿名分组所匹配到的内容。RevSuit 将会检查 `flagGroup` 是否已经在之前的连接中被捕获过,只有当 `flagGroup`
|
||||
是首次出现时,才会推送 `flag`
|
||||
到客户端。
|
||||
|
||||
以针对 SSRF 漏洞扫描为例:
|
||||
|
||||
首先我们创建一个如下的规则:
|
||||
|
||||
```yaml
|
||||
http:
|
||||
- name: ssrf
|
||||
flag_format: (ssrf[a-z0-9]{6})[0-9]{1,3}
|
||||
rank: 0
|
||||
push_to_client: false
|
||||
notice: false
|
||||
response_status_code: "200"
|
||||
response_headers: { }
|
||||
response_body: "Here is a SSRF!"
|
||||
```
|
||||
|
||||
假设我们的目标是 `https://www.testvuln.com?url=api.com&p=useless`,并且针对 SSRF 漏洞,我们有5个
|
||||
payload,最后被扫描器发出的请求是:`['https://www.testvuln.com?url=http://revsuit.com/ssrfa98oni1&p=useless','https://www.testvuln.com?url=http://revsuit.com/ssrfa98oni2&p=useless', ... ,'https://www.testvuln.com?url=//revsuit.com/ssrfa98oni5&p=useless`']
|
||||
,它们可能全部攻击成功.
|
||||
|
||||
然而,因为我们在规则的 `flagFormat` 中使用了匿名分组,RevSuit 将会在数据库中查询连接的 `flagGroup`,在这个例子里也就是 `ssrfa98oni` ,只有当它是第一次出现时,才会向客户端推送 `flag`
|
||||
,所以客户端只会收到 `ssrfa98oni1` 这一个 `flag` ,这足以确认这个请求的 URL 参数存在漏洞了。
|
||||
|
||||
### 多模块联动
|
||||
|
||||
在实际的渗透测试场景中,一些特定的操作可以通过 RevSuit 多个模块配合,快速、简单地完成。下面以一个 Java Web 环境中 盲XXE 漏洞利用场景为例,展示如何使用 RevSuit 的 HTTP 和 FTP
|
||||
模块,配合模板变量,快速完成内网端口扫描。
|
||||
|
||||
首先创建一个 HTTP 规则来返回 evil.dtd, 使被攻击的目标去连接 RevSuit 的 FTP 模块,并且通过设置 FTP 连接的用户名和密码为模板变量来传递我们要扫描的 IP 和端口。
|
||||
|
||||

|
||||
|
||||
然后创建一个 FTP 规则,其中 `Pasv Address` 的 Host 和 Port 通过模板变量从 FTP 连接的用户名和密码动态获取。
|
||||
|
||||

|
||||
|
||||
然后使用 BurpSuit 即可进行扫描,通过设置 evil.dtd 请求中的 host 和 post 参数,来指定要扫描的目标端口:
|
||||
|
||||

|
||||
|
||||
运行效果如下:
|
||||
|
||||

|
||||
|
||||
因为在 FTP被动模式 中如果 `Passive Address` 是不可达的, FTP 的连接会中断,因此我们可以通过检查 FTP 的连接是否正常退出,来判断端口是否开放。对于上面这个例子,我们成功的探测出 8005 端口和 8080
|
||||
端口是开放的。
|
||||
|
||||
## 更多用法
|
||||
|
||||
一个更详细的 wiki 正在准备中,在此之前你可以自己探索...
|
||||
|
||||
## 反馈、建议与交流
|
||||
|
||||
提交 Issue 或者通过微信联系我`TGk0bjA2Cg==`
|
||||
|
||||
## 致谢
|
||||
|
||||
### 引用
|
||||
|
||||
本项目引用了如下优秀项目的代码:
|
||||
|
||||
* [https://github.com/rmb122/rogue_mysql_server](https://github.com/rmb122/rogue_mysql_server)
|
||||
* [https://github.com/256dpi/newdns](https://github.com/256dpi/newdns)
|
||||
* [https://github.com/EmYiQing/JNDIScan](https://github.com/EmYiQing/JNDIScan)
|
||||
|
||||
### 特别感谢
|
||||
|
||||
感谢我的朋友[@E99p1ant](https://github.com/wuhan005/) 在我开发这个项目过程中给予非常多的建议和帮助。
|
||||
|
||||
## 开源许可协议
|
||||
|
||||
@Apache License 2.0
|
||||
Executable
BIN
Binary file not shown.
Vendored
-1
@@ -1 +0,0 @@
|
||||
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-1bc6d13e],html[data-v-1bc6d13e]{height:100%;margin:0}.fade-transform-enter-active[data-v-1bc6d13e],.fade-transform-leave-active[data-v-1bc6d13e]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-1bc6d13e],.fade-transform-leave[data-v-1bc6d13e]{opacity:0}.fade-transform-enter-to[data-v-1bc6d13e]{opacity:0}.ant-menu-item>span>a[data-v-1bc6d13e]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-1bc6d13e]{color:#fff}#app[data-v-1bc6d13e]{min-height:100%}#app .trigger[data-v-1bc6d13e]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#app .trigger[data-v-1bc6d13e]:hover{color:#1890ff}#app .logo[data-v-1bc6d13e]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-1bc6d13e]{color:#888;text-align:right;margin-right:1rem}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-50ca3b7c]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-4fed8448]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.gray-table-row{background-color:#f5f5f5}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-1f4c0376]{margin-bottom:10px}.full-screen-icon[data-v-1f4c0376]{position:absolute;z-index:5;color:#9e9e9e;right:1px;font-size:1rem;cursor:pointer;transition:font-size .1s}.full-screen-icon[data-v-1f4c0376]:hover{font-size:1.1rem;transition:font-size .1s}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-1361da51]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.gray-table-row{background-color:#f5f5f5}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-6f29426c]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.gray-table-row{background-color:#f5f5f5}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.gray-table-row{background-color:#f5f5f5}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.gray-table-row{background-color:#f5f5f5}
|
||||
Vendored
-8
File diff suppressed because one or more lines are too long
Vendored
-1
@@ -1 +0,0 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>RevSuit Control Panel</title><link href="/revsuit/admin/css/chunk-016c45cf.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-0cb5e9e6.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-193ec343.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-36508a38.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-43748c28.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-46a53d26.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-49fbda44.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-5fb70d83.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-72839f90.css" rel="prefetch"><link href="/revsuit/admin/css/chunk-740736c7.css" rel="prefetch"><link href="/revsuit/admin/js/chunk-016c45cf.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-0cb5e9e6.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-193ec343.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-27186dd0.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-36508a38.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-43748c28.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-46a53d26.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-49fbda44.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-5fb70d83.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-72839f90.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-740736c7.js" rel="prefetch"><link href="/revsuit/admin/js/chunk-b241c712.js" rel="prefetch"><link href="/revsuit/admin/css/app.css" rel="preload" as="style"><link href="/revsuit/admin/css/chunk-vendors.css" rel="preload" as="style"><link href="/revsuit/admin/js/app.js" rel="preload" as="script"><link href="/revsuit/admin/js/chunk-vendors.js" rel="preload" as="script"><link href="/revsuit/admin/css/chunk-vendors.css" rel="stylesheet"><link href="/revsuit/admin/css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but revsuit-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/revsuit/admin/js/chunk-vendors.js"></script><script src="/revsuit/admin/js/app.js"></script></body></html>
|
||||
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-299
File diff suppressed because one or more lines are too long
Generated
+14
-15
@@ -19,7 +19,7 @@
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/cli-service": "^4.5.11",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
@@ -4810,8 +4810,7 @@
|
||||
"node_modules/de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
|
||||
"integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.3.1",
|
||||
@@ -6899,7 +6898,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
|
||||
"integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"he": "bin/he"
|
||||
}
|
||||
@@ -13521,7 +13519,6 @@
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.12.tgz",
|
||||
"integrity": "sha1-lH7XGWdEyKUoXr4SM/6WBDf8xX4=",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"de-indent": "^1.0.2",
|
||||
"he": "^1.1.0"
|
||||
@@ -16436,7 +16433,8 @@
|
||||
"version": "4.5.11",
|
||||
"resolved": "https://registry.npm.taobao.org/@vue/cli-plugin-vuex/download/@vue/cli-plugin-vuex-4.5.11.tgz?cache=0&sync_timestamp=1615453605559&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40vue%2Fcli-plugin-vuex%2Fdownload%2F%40vue%2Fcli-plugin-vuex-4.5.11.tgz",
|
||||
"integrity": "sha1-9vYZvPtmyGzEU0DXMVKERjXlSL0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@vue/cli-service": {
|
||||
"version": "4.5.11",
|
||||
@@ -16590,7 +16588,8 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/@vue/preload-webpack-plugin/download/@vue/preload-webpack-plugin-1.1.2.tgz",
|
||||
"integrity": "sha1-zrkktOyzucQ4ccekKaAvhCPmIas=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@vue/web-component-wrapper": {
|
||||
"version": "1.3.0",
|
||||
@@ -16805,7 +16804,8 @@
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npm.taobao.org/acorn-jsx/download/acorn-jsx-5.3.1.tgz",
|
||||
"integrity": "sha1-/IZh4Rt6wVOcR9v+oucrOvNNJns=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "7.2.0",
|
||||
@@ -16853,13 +16853,15 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/ajv-errors/download/ajv-errors-1.0.1.tgz?cache=0&sync_timestamp=1615411237786&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-errors%2Fdownload%2Fajv-errors-1.0.1.tgz",
|
||||
"integrity": "sha1-81mGrOuRr63sQQL72FAUlQzvpk0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npm.taobao.org/ajv-keywords/download/ajv-keywords-3.5.2.tgz?cache=0&sync_timestamp=1615647295573&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fajv-keywords%2Fdownload%2Fajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha1-MfKdpatuANHC0yms97WSlhTVAU0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"alphanum-sort": {
|
||||
"version": "1.0.2",
|
||||
@@ -18899,8 +18901,7 @@
|
||||
"de-indent": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npm.taobao.org/de-indent/download/de-indent-1.0.2.tgz",
|
||||
"integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
@@ -20633,8 +20634,7 @@
|
||||
"he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/he/download/he-1.2.0.tgz",
|
||||
"integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
|
||||
},
|
||||
"hex-color-regex": {
|
||||
"version": "1.1.0",
|
||||
@@ -26188,7 +26188,6 @@
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npm.taobao.org/vue-template-compiler/download/vue-template-compiler-2.6.12.tgz",
|
||||
"integrity": "sha1-lH7XGWdEyKUoXr4SM/6WBDf8xX4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"de-indent": "^1.0.2",
|
||||
"he": "^1.1.0"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/cli-service": "^4.5.11",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2",
|
||||
|
||||
+54
-10
@@ -21,6 +21,9 @@
|
||||
<a-menu-item key="/logs/rmi">
|
||||
<router-link to="/logs/rmi">RMI Logs</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="/logs/ldap">
|
||||
<router-link to="/logs/ldap">LDAP Logs</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="/logs/mysql">
|
||||
<router-link to="/logs/mysql">MySQL Logs</router-link>
|
||||
</a-menu-item>
|
||||
@@ -39,6 +42,9 @@
|
||||
<a-menu-item key="/rules/rmi">
|
||||
<router-link to="/rules/rmi">RMI Rules</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="/rules/ldap">
|
||||
<router-link to="/rules/ldap">LDAP Rules</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="/rules/mysql">
|
||||
<router-link to="/rules/mysql">MySQL Rules</router-link>
|
||||
</a-menu-item>
|
||||
@@ -62,7 +68,7 @@
|
||||
/>
|
||||
<div v-if="isLogMode" style="float: right; min-width:60% ;padding: 12px 0;line-height: 24px;">
|
||||
<a-row :gutter="24" type="flex">
|
||||
<a-col :span="21">
|
||||
<a-col :span="20">
|
||||
<a-form-model v-show="showSettings" ref="settings" layout="inline">
|
||||
<a-row :gutter="24" type="flex">
|
||||
<a-col :span="9" :offset="2">
|
||||
@@ -80,9 +86,23 @@
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
</a-col>
|
||||
<a-col :span="3">
|
||||
<a-col :span="4">
|
||||
<a-popconfirm
|
||||
:title="showLogNum?`This will delete all logs in the current filtered state, a total of ${this.$refs.content.pagination.total}, are you sure?`:'This will delete all logs in the current filtered state, a total of 0, are you sure?'"
|
||||
ok-text="Yes"
|
||||
cancel-text="No"
|
||||
@visibleChange="showLogNum?delayChangeShowLogNum():showLogNum=!showLogNum"
|
||||
@confirm="deleteLogs"
|
||||
>
|
||||
<a-icon slot="icon" type="question-circle-o" style="color: red"/>
|
||||
<a-icon
|
||||
:style="'font-size: 18px;padding: 12px 0;'"
|
||||
type="delete"
|
||||
@click="()=>{}"
|
||||
/>
|
||||
</a-popconfirm>
|
||||
<a-icon
|
||||
:style="'font-size: 18px;padding: 12px 0;'+(showSettings?'color: #1b90ff;':'')"
|
||||
:style="'font-size: 18px;padding:12px 15px;'+(showSettings?'color: #1b90ff;':'')"
|
||||
type="setting"
|
||||
@click="showSettings = !showSettings"
|
||||
/>
|
||||
@@ -98,10 +118,17 @@
|
||||
</transition>
|
||||
</a-layout-content>
|
||||
<div class="copyright">
|
||||
<p class="">
|
||||
RevSuit Current Version: {{ this.version }} ©2021 <a href="https://github.com/Li4n0">Li4n0</a>. <a
|
||||
<p v-if="!this.upgrade.upgradeable">
|
||||
RevSuit Current Version: {{ this.version }}|© 2021 <a href="https://github.com/Li4n0">Li4n0</a>|<a
|
||||
href="https://github.com/Li4n0/revsuit">GitHub</a>
|
||||
</p>
|
||||
<p v-else>
|
||||
RevSuit {{ this.version }}(Upgrade Available: <a
|
||||
target="_blank"
|
||||
:href="this.upgrade.release">v{{ this.upgrade.version }}</a>)|© 2021 <a
|
||||
href="https://github.com/Li4n0">Li4n0</a>|<a href="https://github.com/Li4n0/revsuit">GitHub</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</a-layout>
|
||||
<Auth></Auth>
|
||||
@@ -110,7 +137,7 @@
|
||||
<script>
|
||||
import Auth from '@/components/Auth'
|
||||
import RuleIcon from "@/components/Icon";
|
||||
import {getVersion} from "@/api/auth";
|
||||
import {getVersion, getUpgrade} from "@/api/version";
|
||||
import {store} from "@/main";
|
||||
|
||||
|
||||
@@ -123,14 +150,16 @@ export default {
|
||||
pageSize: store.pageSize,
|
||||
collapsed: false,
|
||||
showSettings: false,
|
||||
showLogNum: false,
|
||||
openKeys: [],
|
||||
version: "",
|
||||
upgrade: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isLogMode() {
|
||||
return this.$route.path.includes('logs')
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
timing() {
|
||||
@@ -141,17 +170,31 @@ export default {
|
||||
this.$refs.content.fetch()
|
||||
}, this.refreshInterval * 1000)
|
||||
},
|
||||
GetVersion() {
|
||||
_getVersion() {
|
||||
getVersion().then(res => {
|
||||
this.version = res.data.result
|
||||
})
|
||||
},
|
||||
_getUpgrade() {
|
||||
getUpgrade().then(res => {
|
||||
this.upgrade = res.data.result
|
||||
})
|
||||
},
|
||||
deleteLogs() {
|
||||
this.$refs.content.delete()
|
||||
},
|
||||
delayChangeShowLogNum() {
|
||||
setTimeout(() => {
|
||||
this.showLogNum = !this.showLogNum
|
||||
}, 1000)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (localStorage.getItem("autoRefresh") === null) {
|
||||
this.autoRefresh = true;
|
||||
}
|
||||
this.GetVersion()
|
||||
this._getVersion()
|
||||
this._getUpgrade()
|
||||
},
|
||||
created() {
|
||||
let unwatch = this.$watch('$route', function (to, from) {
|
||||
@@ -195,7 +238,8 @@ export default {
|
||||
'store.authed'(val) {
|
||||
if (val) {
|
||||
this.$refs.content.fetch()
|
||||
this.GetVersion()
|
||||
this._getVersion()
|
||||
this._getUpgrade()
|
||||
}
|
||||
},
|
||||
'store.pageSize'() {
|
||||
|
||||
@@ -6,11 +6,4 @@ export function auth(token) {
|
||||
method: 'get',
|
||||
headers: {"Token": token},
|
||||
})
|
||||
}
|
||||
|
||||
export function getVersion() {
|
||||
return request({
|
||||
url: '/version',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import axios from 'axios'
|
||||
import {store} from "@/main";
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: location.pathname.slice(0, -'/admin/'.length) + "/api", // api的base_url
|
||||
baseURL: "../api", // api的base_url
|
||||
timeout: 5000, // request timeout
|
||||
validateStatus: function (status) {
|
||||
if (status === 403) {
|
||||
@@ -12,4 +12,4 @@ const service = axios.create({
|
||||
}
|
||||
})
|
||||
|
||||
export default service
|
||||
export default service
|
||||
|
||||
@@ -9,6 +9,15 @@ export function getHttpRecord(params) {
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteHttpRecord(params) {
|
||||
return request({
|
||||
url: '/record/http',
|
||||
params: params,
|
||||
method: 'delete',
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
export function getDnsRecord(params) {
|
||||
return request({
|
||||
url: '/record/dns',
|
||||
@@ -17,6 +26,14 @@ export function getDnsRecord(params) {
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteDnsRecord(params) {
|
||||
return request({
|
||||
url: '/record/dns',
|
||||
params: params,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getMysqlRecord(params) {
|
||||
return request({
|
||||
url: '/record/mysql',
|
||||
@@ -25,6 +42,14 @@ export function getMysqlRecord(params) {
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteMysqlRecord(params) {
|
||||
return request({
|
||||
url: '/record/mysql',
|
||||
params: params,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getRmiRecord(params) {
|
||||
return request({
|
||||
url: '/record/rmi',
|
||||
@@ -33,10 +58,42 @@ export function getRmiRecord(params) {
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteRmiRecord(params) {
|
||||
return request({
|
||||
url: '/record/rmi',
|
||||
params: params,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getLdapRecord(params) {
|
||||
return request({
|
||||
url: '/record/ldap',
|
||||
params: params,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteLdapRecord(params) {
|
||||
return request({
|
||||
url: '/record/ldap',
|
||||
params: params,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getFtpRecord(params) {
|
||||
return request({
|
||||
url: '/record/ftp',
|
||||
params: params,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteFtpRecord(params) {
|
||||
return request({
|
||||
url: '/record/ftp',
|
||||
params: params,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -97,6 +97,30 @@ export function deleteRmiRule(data) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getLdapRule(params) {
|
||||
return request({
|
||||
url: '/rule/ldap',
|
||||
params: params,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function upsertLdapRule(data) {
|
||||
return request({
|
||||
url: '/rule/ldap',
|
||||
data: data,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteLdapRule(data) {
|
||||
return request({
|
||||
url: '/rule/ldap',
|
||||
data: data,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
export function getFtpRule(params) {
|
||||
return request({
|
||||
url: '/rule/ftp',
|
||||
|
||||
@@ -42,6 +42,20 @@ export function updateRmiConfig(data) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getLdapConfig() {
|
||||
return request({
|
||||
url: '/setting/getLdapConfig',
|
||||
})
|
||||
}
|
||||
|
||||
export function updateLdapConfig(data) {
|
||||
return request({
|
||||
url: '/setting/updateLdapConfig',
|
||||
method: "post",
|
||||
data: data,
|
||||
})
|
||||
}
|
||||
|
||||
export function getMySQLConfig() {
|
||||
return request({
|
||||
url: '/setting/getMySQLConfig',
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import request from "@/api/index";
|
||||
|
||||
export function getVersion() {
|
||||
return request({
|
||||
url: '/version',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
export function getUpgrade() {
|
||||
return request({
|
||||
url: '/getUpgrade',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
@@ -30,6 +30,11 @@ const routes = [
|
||||
name: 'RmiLogs',
|
||||
component: () => import( '../views/logs/Rmi')
|
||||
},
|
||||
{
|
||||
path: '/logs/ldap',
|
||||
name: 'LdapLogs',
|
||||
component: () => import( '../views/logs/Ldap')
|
||||
},
|
||||
{
|
||||
path: '/logs/ftp',
|
||||
name: 'FtpLogs',
|
||||
@@ -56,6 +61,11 @@ const routes = [
|
||||
name: 'RmiRules',
|
||||
component: () => import( '../views/rules/Rmi')
|
||||
},
|
||||
{
|
||||
path: '/rules/ldap',
|
||||
name: 'LdapRules',
|
||||
component: () => import( '../views/rules/Ldap')
|
||||
},
|
||||
{
|
||||
path: '/rules/ftp',
|
||||
name: 'FtpRules',
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getDnsRecord} from '@/api/record'
|
||||
import {deleteDnsRecord, getDnsRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
@@ -82,6 +82,15 @@ const columns = [
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'VALUE',
|
||||
dataIndex: 'value',
|
||||
key: 'value',
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'REMOTE IP',
|
||||
key: 'remote_ip',
|
||||
@@ -145,6 +154,21 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteDnsRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<a-tag
|
||||
v-if="file"
|
||||
color="#f5222d"
|
||||
><a target="_blank" :href="'/revsuit/api/file/ftp/'+file.id">TRUE</a> </a-tag>
|
||||
><a target="_blank" :href="'../api/file/ftp/'+file.id">TRUE</a> </a-tag>
|
||||
<a-tag v-else color="#722ed1">
|
||||
FALSE
|
||||
</a-tag>
|
||||
@@ -72,7 +72,7 @@
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getFtpRecord} from '@/api/record'
|
||||
import {deleteFtpRecord, getFtpRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
@@ -234,6 +234,21 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteFtpRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getHttpRecord} from '@/api/record'
|
||||
import {getHttpRecord, deleteHttpRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
@@ -179,6 +179,21 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteHttpRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
|
||||
@@ -0,0 +1,173 @@
|
||||
<template>
|
||||
<a-table
|
||||
style="overflow-x: auto;"
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
@change="handleTableChange"
|
||||
:rowClassName="(record, index) => index % 2 === 0 ? '' : 'gray-table-row'"
|
||||
>
|
||||
<filter-dropdown
|
||||
slot="filterDropdown"
|
||||
slot-scope="{ setSelectedKeys, selectedKeys, clearFilters, column }"
|
||||
:set-selected-keys="setSelectedKeys"
|
||||
:selected-keys="selectedKeys"
|
||||
:clear-filters="clearFilters"
|
||||
:column="column"
|
||||
:filters="filters"
|
||||
:fetch="fetch"
|
||||
/>
|
||||
<a-icon
|
||||
slot="filterIcon"
|
||||
slot-scope="filtered"
|
||||
type="search"
|
||||
:style="{ color: filtered ? '#108ee9' : undefined }"
|
||||
/>
|
||||
|
||||
<span slot="time" slot-scope="time">
|
||||
{{ new Date(time).format("yyyy-MM-dd hh:mm:ss") }}
|
||||
</span>
|
||||
</a-table>
|
||||
</template>
|
||||
<style>
|
||||
.gray-table-row {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {deleteLdapRecord, getLdapRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
sorter: true,
|
||||
sortDirections: ['descend', 'ascend'],
|
||||
},
|
||||
{
|
||||
title: 'REQUEST TIME',
|
||||
dataIndex: 'request_time',
|
||||
key: 'request_time',
|
||||
scopedSlots: {customRender: 'time'},
|
||||
},
|
||||
{
|
||||
title: 'RULE',
|
||||
dataIndex: 'rule_name',
|
||||
key: 'rule_name',
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'FLAG',
|
||||
dataIndex: 'flag',
|
||||
key: 'flag',
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'PATH',
|
||||
dataIndex: 'path',
|
||||
key: 'path',
|
||||
ellipsis: true,
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'REMOTE IP',
|
||||
key: 'remote_ip',
|
||||
dataIndex: 'remote_ip',
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'IP AREA',
|
||||
key: 'ip_area',
|
||||
dataIndex: 'ip_area'
|
||||
}
|
||||
];
|
||||
|
||||
export default {
|
||||
name: 'LdapLogs',
|
||||
data() {
|
||||
return {
|
||||
store,
|
||||
data: [],
|
||||
pagination: {
|
||||
current: 1, showSizeChanger: true, pageSize: store.pageSize,
|
||||
onShowSizeChange: (current, size) => {
|
||||
store.pageSize = size
|
||||
}
|
||||
},
|
||||
filters: {},
|
||||
order: "desc",
|
||||
loading: false,
|
||||
columns,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
const pager = {...this.pagination};
|
||||
pager.current = pagination.current;
|
||||
this.pagination = pager;
|
||||
this.order = sorter.order === "ascend" ? "asc" : "desc"
|
||||
this.fetch();
|
||||
},
|
||||
fetch: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
page: this.pagination.current,
|
||||
pageSize: this.pagination.pageSize,
|
||||
order: this.order
|
||||
}
|
||||
this.loading = true;
|
||||
getLdapRecord(params).then(res => {
|
||||
let result = res.data.result
|
||||
this.data = result.data
|
||||
const pagination = {...this.pagination};
|
||||
|
||||
pagination.total = result.count;
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Unknown error with status code: ' + e.response.status)
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteLdapRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
},
|
||||
components: {
|
||||
FilterDropdown
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -10,7 +10,7 @@
|
||||
>
|
||||
<div v-if="record.files.length" slot="expandedRowRender" slot-scope="record" style="margin: 0">
|
||||
<b v-if="record.files.length" style="color: gray">FILES:</b><br>
|
||||
<a v-for="file in record.files" :key="file.name+record.id" :href="'/revsuit/api/file/mysql/'+file.id"
|
||||
<a v-for="file in record.files" :key="file.name+record.id" :href="'../api/file/mysql/'+file.id"
|
||||
target="_blank">{{ file.name }} </a>
|
||||
</div>
|
||||
<div slot="selectDropdown"
|
||||
@@ -70,7 +70,7 @@
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getMysqlRecord} from '@/api/record'
|
||||
import {deleteMysqlRecord, getMysqlRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
@@ -231,6 +231,21 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteMysqlRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getRmiRecord} from '@/api/record'
|
||||
import {deleteRmiRecord, getRmiRecord} from '@/api/record'
|
||||
import {store} from '@/main'
|
||||
import FilterDropdown from '@/components/FilterDropdown'
|
||||
|
||||
@@ -110,7 +110,8 @@ export default {
|
||||
onShowSizeChange: (current, size) => {
|
||||
store.pageSize = size
|
||||
}
|
||||
}, filters: {},
|
||||
},
|
||||
filters: {},
|
||||
order: "desc",
|
||||
loading: false,
|
||||
columns,
|
||||
@@ -146,6 +147,21 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
delete: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
}
|
||||
this.loading = true;
|
||||
deleteRmiRecord(params).then(() => {
|
||||
this.$message.success('Deleted successfully')
|
||||
this.filters = {}
|
||||
this.fetch()
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Failed to delete: ' + e.response.data.error)
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch();
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
<span slot="label">
|
||||
Value
|
||||
<a-tooltip
|
||||
title="Support template such as ${varname}">
|
||||
title="Support template such as ${flag}/${custom_varname}">
|
||||
<a-icon type="question-circle-o"/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
@@ -90,7 +90,7 @@
|
||||
</a-drawer>
|
||||
<!-- rule table -->
|
||||
<a-table
|
||||
style="overflow-x: auto;"
|
||||
style="overflow-x: auto;"
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
:loading="loading"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
<a-tooltip
|
||||
title="1. The data to be returned when the client executes the download request.
|
||||
2. Please use base64 encoding.
|
||||
3. Support template such as ${user}/${password}/${varname}">
|
||||
3. Support template such as ${user}/${password}/${flag}/${custom_varname}">
|
||||
<a-icon type="question-circle-o"/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<span slot="label">
|
||||
Response Status Code
|
||||
<a-tooltip
|
||||
title="Number between 100-600, or template such as ${query.varname}/${body.varname}/${header.varname}">
|
||||
title="Number between 100-600, or template such as ${query.varname}/${body.varname}/${header.varname}/${flag}/${custom_varname}">
|
||||
<a-icon type="question-circle-o"/>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
<template xmlns:a-col="http://www.w3.org/1999/html">
|
||||
<div>
|
||||
<a-button id="add-rule" type="primary" @click="addRule">
|
||||
<a-icon type="plus"/>
|
||||
New Rule
|
||||
</a-button>
|
||||
<!-- rule form-->
|
||||
<a-drawer
|
||||
:title="formAction+ ' RMI rule'"
|
||||
:width="490"
|
||||
:visible="formVisible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="closeDrawer"
|
||||
>
|
||||
<a-form-model :model="form" ref="form" layout="vertical" @submit="handleSubmit">
|
||||
<BasicRule :form="form" :readOnly="formReadOnly" flagFormat="path"/>
|
||||
</a-form-model>
|
||||
<div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e9e9e9',
|
||||
padding: '10px 16px',
|
||||
background: '#fff',
|
||||
textAlign: 'right',
|
||||
zIndex: 1,
|
||||
}"
|
||||
>
|
||||
<a-button :style="{ marginRight: '8px' }" @click="handleCancel">
|
||||
Cancel
|
||||
</a-button>
|
||||
<a-button type="primary" :disabled="formReadOnly" @click="handleSubmit">
|
||||
Submit
|
||||
</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
<!-- rule table -->
|
||||
<a-table
|
||||
style="overflow-x: auto;"
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
:loading="loading"
|
||||
:pagination="pagination"
|
||||
@change="handleTableChange"
|
||||
>
|
||||
<div
|
||||
slot="filterDropdown"
|
||||
slot-scope="{ setSelectedKeys, selectedKeys, clearFilters, column }"
|
||||
style="padding: 8px"
|
||||
>
|
||||
<a-input
|
||||
:placeholder="`Search ${column.dataIndex}`"
|
||||
:value="selectedKeys[0]"
|
||||
style="width: 188px; margin-bottom: 8px; display: block;"
|
||||
@change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])"
|
||||
@pressEnter="() => {filters[column.dataIndex] = selectedKeys[0];fetch()}"
|
||||
/>
|
||||
<a-button
|
||||
type="primary"
|
||||
icon="search"
|
||||
size="small"
|
||||
style="width: 90px; margin-right: 8px"
|
||||
@click="() => {filters[column.dataIndex] = selectedKeys[0];fetch()}"
|
||||
>
|
||||
Search
|
||||
</a-button>
|
||||
</div>
|
||||
<a-icon
|
||||
slot="filterIcon"
|
||||
slot-scope="filtered"
|
||||
type="search"
|
||||
:style="{ color: filtered ? '#108ee9' : undefined }"
|
||||
/>
|
||||
<span slot="rank" slot-scope="rank">
|
||||
<a-tag
|
||||
:color="'#'+(0x2db7f5+rank*80).toString(16)"
|
||||
>
|
||||
{{ rank }}
|
||||
</a-tag>
|
||||
</span>
|
||||
|
||||
<span slot="switchRender" slot-scope="checked,record,index,dataIndex">
|
||||
<a-switch :checked="checked" @click="clickSwitch(record,dataIndex.dataIndex)"></a-switch>
|
||||
</span>
|
||||
<span slot="valueRender" slot-scope="values">
|
||||
<span v-for="value in values.split(',')" :key="value">{{ value }}<br/></span>
|
||||
</span>
|
||||
<span slot="action" slot-scope="text,record,index">
|
||||
<a-button @click="viewRule(record)" style="
|
||||
color: #67C23A;
|
||||
background-color: transparent;
|
||||
border-color: #67C23A;
|
||||
text-shadow: none;
|
||||
margin:0 10px 3px 0;
|
||||
" size="small" ghost>View</a-button>
|
||||
<a-button @click="editRule(record,index)" style="
|
||||
color: #909399;
|
||||
background-color: transparent;
|
||||
border-color: #909399;
|
||||
text-shadow: none;
|
||||
margin:0 10px 3px 0;
|
||||
" size="small" ghost>Edit</a-button>
|
||||
<a-popconfirm
|
||||
title="Are you sure delete this task?"
|
||||
ok-text="Yes"
|
||||
cancel-text="No"
|
||||
@confirm="deleteRule(record,index)"
|
||||
>
|
||||
<a-button type="danger" size="small" ghost>Delete</a-button>
|
||||
</a-popconfirm>
|
||||
</span>
|
||||
</a-table>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
#add-rule {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
|
||||
import {getLdapRule, upsertLdapRule, deleteLdapRule} from '@/api/rule'
|
||||
import {store} from '@/main'
|
||||
import BasicRule from "@/components/BasicRule";
|
||||
|
||||
const VIEW = "View"
|
||||
const EDIT = "Edit"
|
||||
const CREATE = "Create"
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
sorter: true,
|
||||
sortDirections: ['descend', 'ascend'],
|
||||
},
|
||||
{
|
||||
title: 'NAME',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
scopedSlots: {
|
||||
filterDropdown: 'filterDropdown',
|
||||
filterIcon: 'filterIcon',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'FLAG FORMAT',
|
||||
dataIndex: 'flag_format',
|
||||
key: 'flag_format',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: 'RANK',
|
||||
dataIndex: 'rank',
|
||||
key: 'rank',
|
||||
scopedSlots: {
|
||||
customRender: 'rank',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'PUSH TO CLIENT',
|
||||
dataIndex: 'push_to_client',
|
||||
key: 'push_to_client',
|
||||
scopedSlots: {
|
||||
customRender: 'switchRender',
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'NOTICE',
|
||||
dataIndex: 'notice',
|
||||
key: 'notice',
|
||||
scopedSlots: {
|
||||
customRender: 'switchRender',
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Action',
|
||||
key: 'action',
|
||||
scopedSlots: {customRender: 'action'},
|
||||
},
|
||||
];
|
||||
export default {
|
||||
name: 'LdapRules',
|
||||
data() {
|
||||
return {
|
||||
store,
|
||||
data: [],
|
||||
formVisible: false,
|
||||
pagination: {
|
||||
current: 1, showSizeChanger: true, pageSize: store.pageSize,
|
||||
onShowSizeChange: (current, size) => {
|
||||
store.pageSize = size
|
||||
}
|
||||
},
|
||||
filters: {},
|
||||
loading: false,
|
||||
columns,
|
||||
form: {},
|
||||
formReadOnly: false,
|
||||
formAction: "", // View ,Create or Edit
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTableChange(pagination, filters, sorter) {
|
||||
const pager = {...this.pagination};
|
||||
pager.current = pagination.current;
|
||||
this.pagination = pager;
|
||||
this.order = sorter.order === "ascend" ? "asc" : "desc"
|
||||
this.fetch();
|
||||
},
|
||||
fetch: function () {
|
||||
let params = {
|
||||
...this.filters,
|
||||
page: this.pagination.current,
|
||||
pageSize: this.pagination.pageSize,
|
||||
order: this.order
|
||||
}
|
||||
this.loading = true;
|
||||
getLdapRule(params).then(res => {
|
||||
let result = res.data.result
|
||||
this.data = result.data
|
||||
const pagination = {...this.pagination};
|
||||
pagination.total = result.count;
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status !== 403) {
|
||||
this.$message.error('Unknown error with status code: ' + e.response.status)
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
record[prop] = !record[prop]
|
||||
upsertLdapRule(record).then().catch(e => {
|
||||
this.$notification.error({
|
||||
message: 'Edit failed',
|
||||
description:
|
||||
e.response.data.error,
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
addRule() {
|
||||
this.form = {}
|
||||
this.showForm(CREATE)
|
||||
},
|
||||
viewRule(record) {
|
||||
this.form = record
|
||||
this.showForm(VIEW)
|
||||
},
|
||||
editRule(record) {
|
||||
this.form = JSON.parse(JSON.stringify(record))
|
||||
this.showForm(EDIT)
|
||||
},
|
||||
deleteRule(record, index) {
|
||||
deleteLdapRule(record).then(() => {
|
||||
this.data.splice(index, 1)
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
message: 'Error',
|
||||
description:
|
||||
e.response.data.error,
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
showForm(action) {
|
||||
this.formAction = action
|
||||
this.formReadOnly = action === VIEW;
|
||||
this.formVisible = true;
|
||||
},
|
||||
closeDrawer() {
|
||||
this.formVisible = false;
|
||||
},
|
||||
handleSubmit() {
|
||||
this.$refs.form.validate(valid => {
|
||||
if (valid) {
|
||||
upsertLdapRule(this.form).then(() => {
|
||||
this.closeDrawer()
|
||||
this.fetch({page: this.pagination.current});
|
||||
this.$notification.info({
|
||||
message: 'Success',
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 2.5
|
||||
});
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
message: this.formAction + ' failed',
|
||||
description:
|
||||
e.response.data.error,
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCancel() {
|
||||
this.form = {}
|
||||
this.closeDrawer()
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.fetch({page: "1"});
|
||||
},
|
||||
components: {
|
||||
BasicRule,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div>
|
||||
<SettingForm :form="form" :spinning="spinning"></SettingForm>
|
||||
<a-result v-if="status"
|
||||
:status="status"
|
||||
:title="title"
|
||||
:sub-title="subTitle"
|
||||
>
|
||||
<template #extra>
|
||||
<a-row>
|
||||
<a-col :span="12" :offset="7">
|
||||
<div style="text-align: left">
|
||||
<li v-for="err in errors" :key="err">{{ err }}</li>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-result>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getLdapConfig, updateLdapConfig} from "@/api/settings"
|
||||
import SettingForm from "@/components/SettingForm";
|
||||
|
||||
export default {
|
||||
name: "Ldap",
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
spinning: false,
|
||||
status: "",
|
||||
title: "",
|
||||
subTitle: "",
|
||||
errors: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getConfig() {
|
||||
getLdapConfig().then(res => {
|
||||
this.form = res.data
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
message: 'Error',
|
||||
description:
|
||||
e.response.data.error,
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
updateConfig() {
|
||||
this.spinning = true
|
||||
let targetConfig = JSON.stringify(this.form)
|
||||
updateLdapConfig(this.form).then(
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
getLdapConfig().then((res) => {
|
||||
this.spinning = false
|
||||
let nowConfig = JSON.stringify(res.data)
|
||||
if (nowConfig !== targetConfig) {
|
||||
this.status = "warning"
|
||||
this.title = "Updating the configuration seems to have failed"
|
||||
this.subTitle = "Please check your config options carefully."
|
||||
}
|
||||
this.form = res.data
|
||||
this.status = ""
|
||||
this.title = ""
|
||||
this.subTitle = ""
|
||||
}
|
||||
)
|
||||
}, 3000)
|
||||
}
|
||||
).catch(e => {
|
||||
this.$notification.error({
|
||||
message: 'Error',
|
||||
description:
|
||||
e.response.data.error,
|
||||
style: {
|
||||
width: '600px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getConfig()
|
||||
},
|
||||
components: {
|
||||
SettingForm
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -3,13 +3,13 @@
|
||||
<a-space size="middle">
|
||||
<a-upload
|
||||
name="rules"
|
||||
action="/revsuit/api/setting/importRules"
|
||||
action="../api/setting/importRules"
|
||||
@change="handleChange"
|
||||
:showUploadList="false"
|
||||
>
|
||||
<a-button type="primary" icon="upload">Import</a-button>
|
||||
</a-upload>
|
||||
<a-button type="primary" icon="download" onclick="window.open('/revsuit/api/setting/exportRules')">Export
|
||||
<a-button type="primary" icon="download" onclick="window.open('../api/setting/exportRules')">Export
|
||||
</a-button>
|
||||
</a-space>
|
||||
<a-result v-if="status"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<http ref="settings" v-if="tabKey==='HTTP'"></http>
|
||||
<dns ref="settings" v-else-if="tabKey==='DNS'"></dns>
|
||||
<rmi ref="settings" v-else-if="tabKey==='RMI'"></rmi>
|
||||
<ldap ref="settings" v-else-if="tabKey==='LDAP'"></ldap>
|
||||
<mysql ref="settings" v-else-if="tabKey==='MYSQL'"></mysql>
|
||||
<ftp ref="settings" v-else-if="tabKey==='FTP'"></ftp>
|
||||
<notice ref="settings" v-else-if="tabKey==='NOTICE'"></notice>
|
||||
@@ -20,6 +21,7 @@
|
||||
import Http from "./Http"
|
||||
import Dns from "./Dns"
|
||||
import Rmi from "./Rmi"
|
||||
import Ldap from "./Ldap"
|
||||
import Mysql from "./Mysql"
|
||||
import Ftp from "./Ftp"
|
||||
import Notice from "./Notice"
|
||||
@@ -33,6 +35,7 @@ export default {
|
||||
{key: "HTTP", tab: "PLATFORM|HTTP"},
|
||||
{key: "DNS", tab: "DNS"},
|
||||
{key: "RMI", tab: "RMI"},
|
||||
{key: "LDAP", tab: "LDAP"},
|
||||
{key: "MYSQL", tab: "MYSQL"},
|
||||
{key: "FTP", tab: "FTP"},
|
||||
{key: "NOTICE", tab: "NOTICE"},
|
||||
@@ -51,6 +54,7 @@ export default {
|
||||
Http,
|
||||
Dns,
|
||||
Rmi,
|
||||
Ldap,
|
||||
Mysql,
|
||||
Ftp,
|
||||
Notice,
|
||||
|
||||
@@ -10,15 +10,12 @@ module.exports = {
|
||||
devServer: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:10000',
|
||||
pathRewrite: {
|
||||
'^/api': '/revsuit/api'
|
||||
}
|
||||
target: 'http://127.0.0.1:10000/revsuit/',
|
||||
}
|
||||
},
|
||||
},
|
||||
productionSourceMap: false,
|
||||
runtimeCompiler: true,
|
||||
filenameHashing: false,
|
||||
publicPath: '/revsuit/admin/',
|
||||
publicPath: '',
|
||||
}
|
||||
|
||||
@@ -1,34 +1,86 @@
|
||||
module github.com/li4n0/revsuit
|
||||
|
||||
go 1.16
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/fatih/color v1.10.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.2.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-playground/validator/v10 v10.4.1 // indirect
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/golang/protobuf v1.4.3 // indirect
|
||||
github.com/jinzhu/now v1.1.2 // indirect
|
||||
github.com/json-iterator/go v1.1.10 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.6 // indirect
|
||||
github.com/miekg/dns v1.1.38
|
||||
github.com/oschwald/geoip2-golang v1.5.0
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/gabriel-vasile/mimetype v1.4.1
|
||||
github.com/gin-gonic/gin v1.8.1
|
||||
github.com/glebarez/sqlite v1.4.6
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/miekg/dns v1.1.50
|
||||
github.com/oschwald/geoip2-golang v1.8.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/rhysd/go-github-selfupdate v1.2.3
|
||||
github.com/sinlov/qqwry-golang v0.0.0-20191204062238-bea9868bbbf4
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/ugorji/go v1.2.4 // indirect
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341 // indirect
|
||||
google.golang.org/protobuf v1.25.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
|
||||
gorm.io/driver/sqlite v1.1.4
|
||||
gorm.io/gorm v1.21.4
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/urfave/cli/v2 v2.16.3
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.3.6
|
||||
gorm.io/driver/postgres v1.3.9
|
||||
gorm.io/gorm v1.23.8
|
||||
unknwon.dev/clog/v2 v2.2.0
|
||||
vitess.io/vitess v0.9.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/axgle/mahonia v0.0.0-20120522011915-5dd783869dfe // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.9.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.17.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.10.0 // indirect
|
||||
github.com/goccy/go-json v0.9.7 // indirect
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-github/v30 v30.1.0 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf // indirect
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
|
||||
github.com/jackc/pgconn v1.12.1 // indirect
|
||||
github.com/jackc/pgio v1.0.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
|
||||
github.com/jackc/pgtype v1.11.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.16.1 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/tcnksm/go-gitconfig v0.1.2 // indirect
|
||||
github.com/ugorji/go/codec v1.2.7 // indirect
|
||||
github.com/ulikunitz/xz v0.5.9 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f // indirect
|
||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210701191553-46259e63a0a9 // indirect
|
||||
google.golang.org/grpc v1.45.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
modernc.org/libc v1.16.8 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.1.1 // indirect
|
||||
modernc.org/sqlite v1.17.3 // indirect
|
||||
)
|
||||
|
||||
@@ -6,11 +6,32 @@ cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6A
|
||||
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 v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
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/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
|
||||
github.com/Azure/azure-storage-blob-go v0.10.0/go.mod h1:ep1edmW+kNQx4UfWM9heESNmQdijykocJ0YOxmMX8SE=
|
||||
@@ -34,7 +55,10 @@ github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3
|
||||
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
|
||||
github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0=
|
||||
github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2oc2f4tzPWic=
|
||||
github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc=
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@@ -52,6 +76,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/aquarapid/vaultlib v0.5.1/go.mod h1:yT7AlEXtuabkxylOc/+Ulyp18tff1+QjgNLTnFWTlOs=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
@@ -63,23 +88,34 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkY
|
||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
||||
github.com/aws/aws-sdk-go v1.28.8/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/axgle/mahonia v0.0.0-20120522011915-5dd783869dfe h1:R4O0vD9Qqgv8/5YHiMTw/7yWq5vlYGptLwSzvF1iKjU=
|
||||
github.com/axgle/mahonia v0.0.0-20120522011915-5dd783869dfe/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
|
||||
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/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
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/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
|
||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/buger/jsonparser v0.0.0-20200322175846-f7e751efca13/go.mod h1:tgcrVJ81GPSF0mz+0nu1Xaz0fazGPrmmJfJtxjbHhUQ=
|
||||
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/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||
github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
|
||||
@@ -98,12 +134,12 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
||||
github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/corpix/uarand v0.1.1/go.mod h1:SFKZvkcRoLqVRFZ4u25xPmp6m9ktANfbpXZ7SJ0/FNU=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyberdelia/go-metrics-graphite v0.0.0-20161219230853-39f87cc3b432/go.mod h1:xwIwAxMvYnVrGJPe2FKx5prTrnAjGOD8zvDOnxnrrkM=
|
||||
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
|
||||
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -121,31 +157,43 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
|
||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gabriel-vasile/mimetype v1.2.0 h1:A6z5J8OhjiWFV91sQ3dMI8apYu/tvP9keDaMM3Xu6p4=
|
||||
github.com/gabriel-vasile/mimetype v1.2.0/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
|
||||
github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q=
|
||||
github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/glebarez/go-sqlite v1.17.3 h1:Rji9ROVSTTfjuWD6j5B+8DtkNvPILoUC3xRhkQzGxvk=
|
||||
github.com/glebarez/go-sqlite v1.17.3/go.mod h1:Hg+PQuhUy98XCxWEJEaWob8x7lhJzhNYF1nZbUiRGIY=
|
||||
github.com/glebarez/sqlite v1.4.6 h1:D5uxD2f6UJ82cHnVtO2TZ9pqsLyto3fpDKHIk2OsR8A=
|
||||
github.com/glebarez/sqlite v1.4.6/go.mod h1:WYEtEFjhADPaPJqL/PGlbQQGINBA3eUAfDNbKFJf/zA=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||
@@ -193,16 +241,20 @@ github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2K
|
||||
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
@@ -212,22 +264,33 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
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.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
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=
|
||||
@@ -235,19 +298,35 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
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=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/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/go-github/v27 v27.0.4/go.mod h1:/0Gr8pJ55COkmv+S/yPKCczSkUPIM/LnFyubufRNIS0=
|
||||
github.com/google/go-github/v30 v30.1.0 h1:VLDx+UolQICEOKu2m4uAoMti1SxuEBAl7RSEG16L+Oo=
|
||||
github.com/google/go-github/v30 v30.1.0/go.mod h1:n8jBpHl45a/rlBUtRJMOG4GhNADUQFEufcolZ95JfU8=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
@@ -268,6 +347,7 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xC
|
||||
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/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.5.0/go.mod h1:LqwrLNW876eYSuUOo4ZLHBcdKc038txr/IMfbLPATa4=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
@@ -307,16 +387,66 @@ github.com/hashicorp/serf v0.9.0/go.mod h1:YL0HO+FifKOW2u1ke99DGVu1zhcpZzNwrLIqB
|
||||
github.com/hashicorp/serf v0.9.2/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/icrowley/fake v0.0.0-20180203215853-4178557ae428/go.mod h1:uhpZMVGznybq1itEKXj6RYw9I71qK4kH+OGMjRC4KEo=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
|
||||
github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
|
||||
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
|
||||
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
|
||||
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
|
||||
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
|
||||
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
|
||||
github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=
|
||||
github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
|
||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
|
||||
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
|
||||
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
|
||||
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
|
||||
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y=
|
||||
github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
|
||||
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
|
||||
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
|
||||
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
|
||||
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
|
||||
github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=
|
||||
github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
|
||||
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
|
||||
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
|
||||
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
|
||||
github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=
|
||||
github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
|
||||
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.2 h1:eVKgfIdy9b6zbWBMgFpfDPoAMifwSZagU9HmEU6zgiI=
|
||||
github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@@ -324,13 +454,15 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
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/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@@ -341,16 +473,24 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/krishicks/yaml-patch v0.0.10/go.mod h1:Sm5TchwZS6sm7RJoyg87tzxm2ZcKzdRE4Q7TjNhPrME=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/looplab/fsm v0.2.0/go.mod h1:p+IElwgCnAByqr2DWMuNbPjgMwqcHvTRZZn3dvKEke0=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -364,29 +504,30 @@ github.com/martini-contrib/auth v0.0.0-20150219114609-fa62c19b7ae8/go.mod h1:ahT
|
||||
github.com/martini-contrib/gzip v0.0.0-20151124214156-6c035326b43f/go.mod h1:jhUB0rZB2TPWqy0yGugKRRictO591eSO7If7O4MfCaA=
|
||||
github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
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/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.38 h1:MtIY+fmHUVVgv1AXzmKMWcwdCYxTRPG1EDjpqF4RCEw=
|
||||
github.com/miekg/dns v1.1.38/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
|
||||
github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1/go.mod h1:vuvdOZLJuf5HmJAJrKV64MmozrSsk+or0PB5dzdfspg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
@@ -406,8 +547,9 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.6.3/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
@@ -423,14 +565,16 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/oschwald/geoip2-golang v1.5.0 h1:igg2yQIrrcRccB1ytFXqBfOHCjXWIoMv85lVJ1ONZzw=
|
||||
github.com/oschwald/geoip2-golang v1.5.0/go.mod h1:xdvYt5xQzB8ORWFqPnqMwZpCpgNagttWdoZLlJQzg7s=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0 h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk=
|
||||
github.com/oschwald/maxminddb-golang v1.8.0/go.mod h1:RXZtst0N6+FY/3qCNmZMBApR19cdQj43/NM9VkrNAis=
|
||||
github.com/oschwald/geoip2-golang v1.8.0 h1:KfjYB8ojCEn/QLqsDU0AzrJ3R5Qa9vFlx3z6SLNcKTs=
|
||||
github.com/oschwald/geoip2-golang v1.8.0/go.mod h1:R7bRvYjOeaoenAp9sKRS8GX5bJWcZ0laWO5+DauEktw=
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
|
||||
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
@@ -438,9 +582,12 @@ github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaR
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
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=
|
||||
@@ -474,9 +621,19 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rhysd/go-github-selfupdate v1.2.3 h1:iaa+J202f+Nc+A8zi75uccC8Wg3omaM7HDeimXA22Ag=
|
||||
github.com/rhysd/go-github-selfupdate v1.2.3/go.mod h1:mp/N8zj6jFfBQy/XMYoWsmfzxazpPAODuqarmPDe2Rg=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
@@ -487,10 +644,14 @@ github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e/go.mod h1:gi+0
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sinlov/qqwry-golang v0.0.0-20191204062238-bea9868bbbf4 h1:61LVBhbJS5O8mK3roLwSUDXBSvdQ2MjnOMqnGCgIRko=
|
||||
github.com/sinlov/qqwry-golang v0.0.0-20191204062238-bea9868bbbf4/go.mod h1:ddgkUYVfqz6Adxc3zINDNKi3NHuq84KhoZju4D024LQ=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sjmudd/stopwatch v0.0.0-20170613150411-f380bf8a9be1/go.mod h1:Pgf1sZ2KrHK8vdRTV5UHGp80LT7HMUKuNAiKC402abY=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -518,15 +679,21 @@ github.com/spyzhov/ajson v0.4.2/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzy
|
||||
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.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tchap/go-patricia v0.0.0-20160729071656-dd168db6051b/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||
github.com/tcnksm/go-gitconfig v0.1.2 h1:iiDhRitByXAEyjgBqsKi9QU4o2TNtv9kPP3RgPgXBPw=
|
||||
github.com/tcnksm/go-gitconfig v0.1.2/go.mod h1:/8EhP4H7oJZdIPyT+/UIsG87kTzrzM4UsLGSItWYCpE=
|
||||
github.com/tebeka/selenium v0.9.9/go.mod h1:5Fr8+pUvU6B1OiPfkdCKdXZyr5znvVkxuPd0NOdZCQc=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tinylib/msgp v1.1.1/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
@@ -536,24 +703,29 @@ github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqri
|
||||
github.com/uber-go/atomic v1.4.0/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.4 h1:cTciPbZ/VSOzCLKclmssnfQ/jyoVyOcJ3aoJyUV1Urc=
|
||||
github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.4 h1:C5VurWRRCKjuENsbM6GYVw8W++WVW9rSxoACKIvxzz8=
|
||||
github.com/ugorji/go/codec v1.2.4/go.mod h1:bWBu1+kIRWcF8uMklKaJrR6fTWQOwAlrIzX22pHwryA=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I=
|
||||
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/urfave/cli/v2 v2.16.3 h1:gHoFIwpPjoyIMbJp/VFd+/vuD0dAgFK4B6DpEMFJfQk=
|
||||
github.com/urfave/cli/v2 v2.16.3/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b/go.mod h1:JNALoWa+nCXR8SmgLluHcBNVJgyejzpKPZk9pX2yXXE=
|
||||
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
|
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||
@@ -562,10 +734,21 @@ go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
|
||||
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||
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-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@@ -573,6 +756,7 @@ golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
golang.org/x/crypto v0.0.0-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-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -582,8 +766,12 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
|
||||
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -591,6 +779,11 @@ golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxT
|
||||
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/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/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=
|
||||
@@ -600,12 +793,21 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
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/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
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.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -627,25 +829,51 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
|
||||
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
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 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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=
|
||||
@@ -661,6 +889,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -668,30 +897,62 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191224085550-c709ea063b76/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341 h1:2/QtM1mL37YmcsT8HaDNHDgTqqFVw+zr8UzMiBVLzYU=
|
||||
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418 h1:9vYwv7OjYaky/tlAeD7C4oC9EsPTlaFl1H2jS++V+ME=
|
||||
golang.org/x/sys v0.0.0-20220804214406-8e32c043e418/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/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-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -705,6 +966,7 @@ golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3
|
||||
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-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
@@ -714,14 +976,48 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
|
||||
golang.org/x/tools v0.0.0-20190624190245-7f2218787638/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201202200335-bef1c476418a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -735,10 +1031,26 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E
|
||||
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/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
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/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@@ -749,16 +1061,48 @@ google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98
|
||||
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 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210701191553-46259e63a0a9 h1:HBPuvo39L0DgfVn9eHR3ki/RjZoUFWa+em77e7KFDfs=
|
||||
google.golang.org/genproto v0.0.0-20210701191553-46259e63a0a9/go.mod h1:yiaVoXHpRzHGyxV3o4DktVWY4mSUErTKaeEOq6C3t3U=
|
||||
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.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -767,19 +1111,26 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.17.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.41.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -798,13 +1149,17 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/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 h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.1.4 h1:PDzwYE+sI6De2+mxAneV9Xs11+ZyKV6oxD3wDGkaNvM=
|
||||
gorm.io/driver/sqlite v1.1.4/go.mod h1:mJCeTFr7+crvS+TRnWc5Z3UvwxUN1BGBLMrf5LA9DYw=
|
||||
gorm.io/gorm v1.20.7/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gorm.io/gorm v1.21.4 h1:J0xfPJMRfHgpVcYLrEAIqY/apdvTIkrltPQNHQLq9Qc=
|
||||
gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.3.6 h1:BhX1Y/RyALb+T9bZ3t07wLnPZBukt+IRkMn8UZSNbGM=
|
||||
gorm.io/driver/mysql v1.3.6/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
|
||||
gorm.io/driver/postgres v1.3.9 h1:lWGiVt5CijhQAg0PWB7Od1RNcBw/jS4d2cAScBcSDXg=
|
||||
gorm.io/driver/postgres v1.3.9/go.mod h1:qw/FeqjxmYqW5dBcYNBsnhQULIApQdk7YuuDPktVi1U=
|
||||
gorm.io/gorm v1.23.7/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE=
|
||||
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -812,6 +1167,8 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
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=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.17.3/go.mod h1:YZ0OTkuw7ipbe305fMpIdf3GLXZKRigjtZaV5gzC2J0=
|
||||
k8s.io/apiextensions-apiserver v0.17.3/go.mod h1:CJbCyMfkKftAd/X/V6OTHYhVn7zXnDdnkUjS1h0GTeY=
|
||||
k8s.io/apimachinery v0.17.3/go.mod h1:gxLnyZcGNdZTCLnq3fgzyg2A5BVCHTNDFrw8AmuJ+0g=
|
||||
@@ -826,12 +1183,40 @@ k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
|
||||
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
|
||||
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
|
||||
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
|
||||
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
|
||||
modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||
modernc.org/libc v1.16.8 h1:Ux98PaOMvolgoFX/YwusFOHBnanXdGRmWgI8ciI2z4o=
|
||||
modernc.org/libc v1.16.8/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU=
|
||||
modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI=
|
||||
modernc.org/sqlite v1.17.3/go.mod h1:10hPVYar9C0kfXuTWGz8s0XtB8uAGymUy51ZzStYe3k=
|
||||
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
|
||||
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06/go.mod h1:/ULNhyfzRopfcjskuui0cTITekDduZ7ycKN3oUT9R18=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 894 KiB |
@@ -6,6 +6,6 @@ const banner = `
|
||||
/ /_/ / _ \ | / /\__ \/ / / / / __/
|
||||
/ _, _/ __/ |/ /___/ / /_/ / / /_
|
||||
/_/ |_|\___/|___//____/\__,_/_/\__/
|
||||
v%s
|
||||
%s
|
||||
https://revsuit.pro
|
||||
`
|
||||
|
||||
+17
-2
@@ -16,6 +16,7 @@ func Start() {
|
||||
log.ConsoleConfig{
|
||||
Level: log.LevelInfo,
|
||||
})
|
||||
defer log.Stop()
|
||||
app := &cli.App{
|
||||
Name: "RevSuit",
|
||||
Usage: "An Open-Sourced Reverse Platform Designed for Receive Various Kinds of Connection",
|
||||
@@ -41,6 +42,15 @@ func Start() {
|
||||
Usage: "load configuration from FILE (default: config.yaml)",
|
||||
},
|
||||
},
|
||||
Commands: []*cli.Command{
|
||||
{
|
||||
Name: "upgrade",
|
||||
Action: func(c *cli.Context) error {
|
||||
checkUpdateFromCli()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
var configFile = "config.yaml"
|
||||
if c.Path("config") != "" {
|
||||
@@ -72,14 +82,19 @@ func Start() {
|
||||
conf.Addr = c.String("addr")
|
||||
}
|
||||
if c.String("token") != "" {
|
||||
conf.Addr = c.String("token")
|
||||
conf.Token = c.String("token")
|
||||
}
|
||||
if c.String("db") != "" {
|
||||
conf.Database = c.String("db")
|
||||
}
|
||||
if c.String("log") != "" {
|
||||
conf.Database = c.String("log")
|
||||
conf.LogLevel = c.String("log")
|
||||
}
|
||||
|
||||
if conf.CheckUpgrade {
|
||||
checkUpdateFromCli()
|
||||
}
|
||||
|
||||
server.New(conf).Run()
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
version: 1.3
|
||||
version: 1.5
|
||||
addr: :10000
|
||||
token:
|
||||
domain:
|
||||
domains: []
|
||||
external_ip: # You need to make sure that your target can access the server through this ip.
|
||||
admin_path_prefix: "/revsuit"
|
||||
database: revsuit.db
|
||||
log_level: info
|
||||
check_upgrade: true
|
||||
|
||||
ip_location_database:
|
||||
database: "qqwry" # qqwry or geoip.
|
||||
@@ -19,6 +20,9 @@ dns:
|
||||
rmi:
|
||||
enable: true
|
||||
addr: :1099
|
||||
ldap:
|
||||
enable: true
|
||||
addr: :1389
|
||||
mysql:
|
||||
enable: true
|
||||
addr: :3306
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/li4n0/revsuit/internal/update"
|
||||
"github.com/li4n0/revsuit/pkg/server"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rhysd/go-github-selfupdate/selfupdate"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
func checkUpdateFromCli() {
|
||||
log.Info("Checking for updates...")
|
||||
if upgradeable, release, err := update.CheckUpgrade(server.VERSION); err != nil {
|
||||
log.Warn(err.Error())
|
||||
} else if upgradeable {
|
||||
err := updateFromCli(release)
|
||||
if err != nil {
|
||||
log.Warn(err.Error())
|
||||
}
|
||||
} else {
|
||||
log.Info("The current version is the latest")
|
||||
}
|
||||
}
|
||||
|
||||
func updateFromCli(release *selfupdate.Release) error {
|
||||
releaseNotes := release.ReleaseNotes
|
||||
releaseNotes = strings.Replace(releaseNotes, "\n\n", "\n", -1)
|
||||
releaseNotes = strings.Replace(releaseNotes, "\r\n\r\n", "\n", -1)
|
||||
releaseNotes = strings.Replace(releaseNotes, "**", "", -1)
|
||||
|
||||
log.Info("New version detected: %s\n%s", release.URL, releaseNotes)
|
||||
log.Warn("Do you want to update to v%s?[Y/n]:", release.Version)
|
||||
|
||||
var upgrade string
|
||||
_, _ = fmt.Scanln(&upgrade)
|
||||
if upgrade != "n" {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
log.Error("error when locate executable path, err: %v", err)
|
||||
}
|
||||
|
||||
assetURL := "https://upgrade.revsuit.pro" + strings.TrimPrefix(release.AssetURL, "https://github.com/Li4n0/revsuit/releases") + "?from=" + server.VERSION
|
||||
|
||||
log.Info("Downloading from %s", assetURL)
|
||||
if err := selfupdate.UpdateTo(assetURL, exe); err != nil {
|
||||
return errors.Wrap(err, "error when download asset")
|
||||
}
|
||||
log.Info("Successfully updated to v%s", release.Version)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+47
-6
@@ -1,13 +1,54 @@
|
||||
package database
|
||||
|
||||
import "gorm.io/gorm"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
var DB *gorm.DB
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func InitDB(driver, dsn string) (err error) {
|
||||
switch driver {
|
||||
case "sqlite":
|
||||
DB, err = NewSqlite3(dsn)
|
||||
var (
|
||||
DB *gorm.DB
|
||||
Driver DriverType
|
||||
Locker sync.Mutex
|
||||
)
|
||||
|
||||
type DriverType = string
|
||||
|
||||
const Sqlite = "sqlite"
|
||||
const Mysql = "mysql"
|
||||
const Postgres = "postgres"
|
||||
const UnknownDatabase = "unknown database"
|
||||
|
||||
func InitDB(dsn string) (err error) {
|
||||
dbName, dbDsn := dbType(dsn)
|
||||
|
||||
switch dbName {
|
||||
case Sqlite:
|
||||
DB, err = NewSqlite3(dbDsn)
|
||||
Driver = Sqlite
|
||||
case Mysql:
|
||||
DB, err = NewMysql(dbDsn)
|
||||
Driver = Mysql
|
||||
case Postgres:
|
||||
DB, err = NewPostgres(dbDsn)
|
||||
Driver = Postgres
|
||||
default:
|
||||
err = errors.New("unsupported database")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func dbType(dsn string) (DriverType, string) {
|
||||
if strings.HasSuffix(dsn, ".db") || strings.HasPrefix(dsn, "sqlite3://") {
|
||||
return Sqlite, strings.TrimPrefix(dsn, "sqlite3://")
|
||||
} else if strings.HasPrefix(dsn, "postgres://") {
|
||||
return Postgres, strings.TrimPrefix(dsn, "postgres://")
|
||||
} else if strings.HasPrefix(dsn, "mysql://") {
|
||||
return Mysql, strings.TrimPrefix(dsn, "mysql://")
|
||||
} else if strings.Contains(dsn, "@tcp") { //兼容上个版本的写法
|
||||
return Mysql, dsn
|
||||
}
|
||||
return UnknownDatabase, dsn
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewMysql(dsn string) (*gorm.DB, error) {
|
||||
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package database
|
||||
|
||||
import (
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func NewPostgres(dsn string) (*gorm.DB, error) {
|
||||
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package database
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gorm.io/driver/sqlite"
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
type File struct {
|
||||
ID uint `gorm:"primarykey" form:"id" json:"id"`
|
||||
RecordID uint `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
|
||||
RecordID uint `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Content []byte `json:"-"`
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
)
|
||||
|
||||
func get(url string) (b []byte, err error) {
|
||||
var resp *http.Response
|
||||
client := http.Client{
|
||||
Timeout: 90 * time.Second,
|
||||
Transport: &http.Transport{
|
||||
@@ -28,11 +29,17 @@ func get(url string) (b []byte, err error) {
|
||||
request, _ := http.NewRequest(http.MethodGet, url, nil)
|
||||
request.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36")
|
||||
|
||||
resp, err := client.Do(request)
|
||||
resp, err = client.Do(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
log.Warn("%v", err)
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
@@ -58,7 +65,6 @@ func extractTarGz(gzipStream io.Reader) error {
|
||||
|
||||
switch header.Typeflag {
|
||||
case tar.TypeReg:
|
||||
log.Trace(header.Name)
|
||||
if !strings.HasSuffix(header.Name, "GeoLite2-City.mmdb") {
|
||||
continue
|
||||
}
|
||||
@@ -66,10 +72,14 @@ func extractTarGz(gzipStream io.Reader) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
if _, err := io.Copy(outFile, tarReader); err != nil {
|
||||
_ = outFile.Close()
|
||||
return err
|
||||
}
|
||||
err = outFile.Close()
|
||||
if err != nil {
|
||||
log.Warn("%v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -21,6 +21,7 @@ const (
|
||||
)
|
||||
|
||||
func get(url string) (b []byte, err error) {
|
||||
var resp *http.Response
|
||||
client := http.Client{
|
||||
Timeout: 90 * time.Second,
|
||||
Transport: &http.Transport{
|
||||
@@ -29,11 +30,17 @@ func get(url string) (b []byte, err error) {
|
||||
request, _ := http.NewRequest("GET", url, nil)
|
||||
request.Header.Add("User-Agent", "Nali/2.1.2 (Nali CLI, https://nali.skk.moe)")
|
||||
|
||||
resp, err := client.Do(request)
|
||||
resp, err = client.Do(request)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
err := Body.Close()
|
||||
if err != nil {
|
||||
log.Warn("%v", err)
|
||||
}
|
||||
}(resp.Body)
|
||||
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
@@ -47,17 +54,25 @@ func getKey(b []byte) (key uint32, err error) {
|
||||
}
|
||||
|
||||
func decrypt(b []byte, key uint32) (_ []byte, err error) {
|
||||
var rc io.ReadCloser
|
||||
for i := 0; i < 0x200; i++ {
|
||||
key *= uint32(0x805)
|
||||
key++
|
||||
key &= uint32(0xff)
|
||||
b[i] = b[i] ^ byte(key)
|
||||
}
|
||||
rc, err := zlib.NewReader(bytes.NewBuffer(b))
|
||||
rc, err = zlib.NewReader(bytes.NewBuffer(b))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
defer func(rc io.ReadCloser) {
|
||||
err := rc.Close()
|
||||
if err != nil {
|
||||
log.Warn("%v", err)
|
||||
}
|
||||
}(rc)
|
||||
|
||||
return io.ReadAll(rc)
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package notice
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -66,7 +66,7 @@ func (d *DingTalk) notice(r record.Record) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode/100 != 2 {
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read HTTP response body")
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package notice
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -81,7 +81,7 @@ func (l *Lark) notice(r record.Record) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode/100 != 2 {
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read HTTP response body")
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package notice
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -79,7 +79,7 @@ func (s *Slack) notice(r record.Record) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode/100 != 2 {
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read HTTP response body")
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package notice
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
@@ -54,7 +54,7 @@ func (w *Weixin) notice(r record.Record) error {
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode/100 != 2 {
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read HTTP response body")
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ type Record interface {
|
||||
}
|
||||
|
||||
type BaseRecord struct {
|
||||
Record `gorm:"-" json:"-"`
|
||||
Record `gorm:"-" json:"-" notice:"-"`
|
||||
ID uint `gorm:"primarykey" form:"id" json:"id" notice:"-"`
|
||||
RuleName string `gorm:"index" form:"rule_name" json:"rule_name" notice:"rule"`
|
||||
Flag string `gorm:"index" form:"flag" json:"flag" `
|
||||
|
||||
@@ -3,7 +3,7 @@ package recycler
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
log "unknwon.dev/clog/v2"
|
||||
@@ -36,7 +36,7 @@ func stack(skip int) []byte {
|
||||
// Print this much at least. If we can't find the source, it won't show.
|
||||
_, _ = fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
|
||||
if file != lastFile {
|
||||
data, err := ioutil.ReadFile(file)
|
||||
data, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
+12
-10
@@ -14,16 +14,17 @@ type Rule interface {
|
||||
}
|
||||
|
||||
type BaseRule struct {
|
||||
Rule `gorm:"-" json:"-" yaml:"-"`
|
||||
ID uint `gorm:"primarykey" form:"id" json:"id" yaml:"-"`
|
||||
CreatedAt time.Time `json:"created_at" yaml:"-"`
|
||||
UpdatedAt time.Time `json:"updated_at" yaml:"-"`
|
||||
Name string `gorm:"index;unique;not null;" form:"name" json:"name"`
|
||||
FlagFormat string `gorm:"unique;not null;" form:"flag_format" json:"flag_format" yaml:"flag_format"`
|
||||
flagCatcher *regexp.Regexp `gorm:"-" json:"-"`
|
||||
Rank int `gorm:"default:0" json:"rank" form:"rank"`
|
||||
PushToClient bool `gorm:"default:false;not null;" form:"push_to_client" json:"push_to_client" yaml:"push_to_client"`
|
||||
Notice bool `gorm:"default:false;not null;" form:"notice" json:"notice"`
|
||||
Rule `gorm:"-" json:"-" yaml:"-"`
|
||||
ID uint `gorm:"primarykey" form:"id" json:"id" yaml:"-"`
|
||||
CreatedAt time.Time `json:"created_at" yaml:"-"`
|
||||
UpdatedAt time.Time `json:"updated_at" yaml:"-"`
|
||||
Name string `gorm:"index;unique;not null;" form:"name" json:"name"`
|
||||
FlagFormat string `gorm:"unique;not null;" form:"flag_format" json:"flag_format" yaml:"flag_format"`
|
||||
flagCatcher *regexp.Regexp `gorm:"-" json:"-"`
|
||||
// base_bank 解决 mysql 中关键字 rank 冲突和 pg 下不能使用 ``
|
||||
Rank int `gorm:"default:0;column:base_rank" json:"rank" form:"rank"`
|
||||
PushToClient bool `gorm:"default:false;not null;" form:"push_to_client" json:"push_to_client" yaml:"push_to_client"`
|
||||
Notice bool `gorm:"default:false;not null;" form:"notice" json:"notice"`
|
||||
}
|
||||
|
||||
func (br BaseRule) Match(s string) (flag, flagGroup string, vars map[string]string) {
|
||||
@@ -60,6 +61,7 @@ func (br BaseRule) Match(s string) (flag, flagGroup string, vars map[string]stri
|
||||
vars[name] = strings.TrimSpace(matched[j])
|
||||
}
|
||||
}
|
||||
vars["flag"] = flag
|
||||
|
||||
return flag, flagGroup, vars
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package update
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/blang/semver"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rhysd/go-github-selfupdate/selfupdate"
|
||||
)
|
||||
|
||||
func CheckUpgrade(currentVersion string) (bool, *selfupdate.Release, error) {
|
||||
latest, found, err := selfupdate.DetectLatest("Li4n0/revsuit")
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "error when detecting version")
|
||||
}
|
||||
|
||||
v, err := semver.Parse(strings.TrimPrefix(currentVersion, "v"))
|
||||
if err != nil {
|
||||
return false, nil, errors.Wrap(err, "error when parse version")
|
||||
}
|
||||
if !found || latest.Version.LTE(v) {
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, latest, nil
|
||||
}
|
||||
+51
-44
@@ -17,11 +17,11 @@ import (
|
||||
|
||||
type Server struct {
|
||||
Config
|
||||
serverDomain string
|
||||
serverIP string
|
||||
rules []*Rule
|
||||
rulesLock sync.RWMutex
|
||||
livingLock sync.Mutex
|
||||
serverDomains []string
|
||||
serverIP string
|
||||
rules []*Rule
|
||||
rulesLock sync.RWMutex
|
||||
livingLock sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -37,8 +37,8 @@ func GetServer() *Server {
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *Server) SetServerDomain(serverDomain string) *Server {
|
||||
s.serverDomain = serverDomain
|
||||
func (s *Server) SetServerDomain(serverDomains []string) *Server {
|
||||
s.serverDomains = serverDomains
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (s *Server) UpdateRules() error {
|
||||
db := database.DB.Model(new(Rule))
|
||||
defer s.rulesLock.Unlock()
|
||||
s.rulesLock.Lock()
|
||||
return errors.Wrap(db.Order("rank desc").Find(&s.rules).Error, "DNS update rules error")
|
||||
return errors.Wrap(db.Order("base_rank desc").Find(&s.rules).Error, "DNS update rules error")
|
||||
}
|
||||
|
||||
func newSet(_rule *Rule, name, value, ip string, _type newdns.Type) []newdns.Set {
|
||||
@@ -126,7 +126,7 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
||||
"ns2.hostmaster.com.",
|
||||
"ns3.hostmaster.com.",
|
||||
},
|
||||
Handler: func(lookedName, remoteAddr string) ([]newdns.Set, error) {
|
||||
Handler: func(lookedName, remoteAddr string) (set []newdns.Set, err error) {
|
||||
ip := strings.Split(remoteAddr, ":")[0]
|
||||
|
||||
for _, _rule := range s.getRules() {
|
||||
@@ -135,12 +135,24 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
||||
continue
|
||||
}
|
||||
|
||||
r, err := newRecord(_rule, flag, domain, ip, ipinfo.Area(ip))
|
||||
if _rule.Value != "" {
|
||||
_type := _rule.Type
|
||||
if _rule.Type == newdns.REBINDING {
|
||||
_type = newdns.A
|
||||
}
|
||||
set = newSet(_rule, name, rule.CompileTpl(_rule.Value, vars), ip, _type)
|
||||
}
|
||||
|
||||
var value string
|
||||
if len(set) > 0 && len(set[0].Records) > 0 {
|
||||
value = set[0].Records[0].Address
|
||||
}
|
||||
r, err := newRecord(_rule, flag, domain, value, ip, ipinfo.Area(ip))
|
||||
if err != nil {
|
||||
log.Warn("DNS record(rule_id:%s) created failed :%s", _rule.Name, err)
|
||||
return nil, nil
|
||||
}
|
||||
log.Info("DNS record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||
log.Info("DNS record[id:%d rule:%s remote_ip:%s, value:%s] has been created", r.ID, _rule.Name, ip, value)
|
||||
|
||||
//only send to client or notify user when this connection recorded first time.
|
||||
var count int64
|
||||
@@ -168,15 +180,7 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
||||
}()
|
||||
}
|
||||
}
|
||||
if _rule.Value != "" {
|
||||
value := rule.CompileTpl(_rule.Value, vars)
|
||||
_type := _rule.Type
|
||||
if _rule.Type == newdns.REBINDING {
|
||||
_type = newdns.A
|
||||
}
|
||||
|
||||
return newSet(_rule, name, value, ip, _type), nil
|
||||
}
|
||||
return set, err
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
@@ -204,9 +208,9 @@ func (s *Server) Run() {
|
||||
defer func() {
|
||||
if s.Enable {
|
||||
log.Error("DNS Server exited unexpectedly")
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
if err := s.UpdateRules(); err != nil {
|
||||
@@ -217,39 +221,42 @@ func (s *Server) Run() {
|
||||
// create server
|
||||
server := newdns.NewServer(newdns.Config{
|
||||
Handler: func(name string) (*newdns.Zone, error) {
|
||||
if name == s.serverDomain+"." {
|
||||
return &newdns.Zone{
|
||||
Name: getZoneName(s.serverDomain),
|
||||
MasterNameServer: "ns1.hostmaster.com.",
|
||||
AllNameServers: []string{
|
||||
"ns1.hostmaster.com.",
|
||||
"ns2.hostmaster.com.",
|
||||
"ns3.hostmaster.com.",
|
||||
},
|
||||
Handler: func(_, remoteAddr string) ([]newdns.Set, error) {
|
||||
return []newdns.Set{
|
||||
{
|
||||
Name: name,
|
||||
Type: newdns.A,
|
||||
TTL: 10,
|
||||
Records: []newdns.Record{
|
||||
{
|
||||
Address: s.serverIP,
|
||||
},
|
||||
}}}, nil
|
||||
}}, nil
|
||||
for _, serverDomain := range s.serverDomains {
|
||||
if name == serverDomain+"." {
|
||||
return &newdns.Zone{
|
||||
Name: getZoneName(serverDomain),
|
||||
MasterNameServer: "ns1.hostmaster.com.",
|
||||
AllNameServers: []string{
|
||||
"ns1.hostmaster.com.",
|
||||
"ns2.hostmaster.com.",
|
||||
"ns3.hostmaster.com.",
|
||||
},
|
||||
Handler: func(_, remoteAddr string) ([]newdns.Set, error) {
|
||||
return []newdns.Set{
|
||||
{
|
||||
Name: name,
|
||||
Type: newdns.A,
|
||||
TTL: 10,
|
||||
Records: []newdns.Record{
|
||||
{
|
||||
Address: s.serverIP,
|
||||
},
|
||||
}}}, nil
|
||||
}}, nil
|
||||
}
|
||||
}
|
||||
return s.newZone(name), nil
|
||||
},
|
||||
})
|
||||
|
||||
// run server
|
||||
log.Info("Starting DNS Server at :53, resolve %s to %s", s.serverDomain, s.serverIP)
|
||||
log.Info("Starting DNS Server at :53, resolve %v to %s", s.serverDomains, s.serverIP)
|
||||
go func() {
|
||||
s.livingLock.Lock()
|
||||
if !s.Enable {
|
||||
server.Close()
|
||||
}
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
err := server.Run(s.Addr)
|
||||
|
||||
+42
-2
@@ -1,6 +1,7 @@
|
||||
package dns
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -8,12 +9,15 @@ import (
|
||||
"github.com/li4n0/revsuit/internal/database"
|
||||
"github.com/li4n0/revsuit/internal/notice"
|
||||
"github.com/li4n0/revsuit/internal/record"
|
||||
"gorm.io/gorm"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
var _ record.Record = (*Record)(nil)
|
||||
|
||||
type Record struct {
|
||||
Domain string `gorm:"index" form:"domain" json:"domain"`
|
||||
Value string `form:"value" json:"value"`
|
||||
|
||||
record.BaseRecord
|
||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||
@@ -27,7 +31,7 @@ func (r Record) Notice() {
|
||||
notice.Notice(r)
|
||||
}
|
||||
|
||||
func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, err error) {
|
||||
func newRecord(rule *Rule, flag, domain, value, remoteIp, ipArea string) (r *Record, err error) {
|
||||
r = &Record{
|
||||
BaseRecord: record.BaseRecord{
|
||||
Flag: flag,
|
||||
@@ -36,12 +40,20 @@ func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, er
|
||||
RequestTime: time.Now(),
|
||||
},
|
||||
Domain: domain,
|
||||
Value: value,
|
||||
Rule: *rule,
|
||||
}
|
||||
|
||||
// sqlite db-level lock to prevent too much write operation lead to error of `database is locked` #54
|
||||
if database.Driver == database.Sqlite {
|
||||
database.Locker.Lock()
|
||||
defer database.Locker.Unlock()
|
||||
}
|
||||
|
||||
return r, database.DB.Create(r).Error
|
||||
}
|
||||
|
||||
func ListRecords(c *gin.Context) {
|
||||
func Records(c *gin.Context) {
|
||||
var (
|
||||
dnsRecord Record
|
||||
res []Record
|
||||
@@ -79,7 +91,35 @@ func ListRecords(c *gin.Context) {
|
||||
if dnsRecord.RuleName != "" {
|
||||
db.Where("rule_name = ?", dnsRecord.RuleName)
|
||||
}
|
||||
if dnsRecord.Value != "" {
|
||||
db.Where("address= ?", dnsRecord.Value)
|
||||
}
|
||||
|
||||
//Delete records
|
||||
if c.Request.Method == http.MethodDelete {
|
||||
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if database.Driver == database.Sqlite {
|
||||
db.Exec("VACUUM")
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
})
|
||||
|
||||
log.Info("%d dns records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
//List records
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
|
||||
+5
-15
@@ -47,7 +47,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
|
||||
[]string{
|
||||
"name",
|
||||
"flag_format",
|
||||
"rank",
|
||||
"base_rank",
|
||||
"type",
|
||||
"value",
|
||||
"ttl",
|
||||
@@ -101,10 +101,7 @@ func ListRules(c *gin.Context) {
|
||||
}
|
||||
|
||||
db := database.DB.Model(&dnsRule)
|
||||
if dnsRule.Name != "" {
|
||||
db.Where("name = ?", dnsRule.Name)
|
||||
}
|
||||
db.Count(&count)
|
||||
db.Where(&dnsRule).Count(&count)
|
||||
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
@@ -120,7 +117,7 @@ func ListRules(c *gin.Context) {
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
if err := db.Order("rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
if err := db.Order("base_rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
@@ -138,10 +135,7 @@ func ListRules(c *gin.Context) {
|
||||
|
||||
// UpsertRules creates or updates dns rule from user submit
|
||||
func UpsertRules(c *gin.Context) {
|
||||
var (
|
||||
dnsRule Rule
|
||||
update bool
|
||||
)
|
||||
var dnsRule Rule
|
||||
|
||||
if err := c.ShouldBind(&dnsRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
@@ -152,10 +146,6 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if dnsRule.ID != 0 {
|
||||
update = true
|
||||
}
|
||||
|
||||
if err := dnsRule.CreateOrUpdate(); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
@@ -165,7 +155,7 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if update {
|
||||
if dnsRule.ID != 0 {
|
||||
log.Trace("DNS rule[id:%d] has been updated", dnsRule.ID)
|
||||
} else {
|
||||
log.Trace("DNS rule[id:%d] has been created", dnsRule.ID)
|
||||
|
||||
+6
-5
@@ -71,7 +71,7 @@ func (s *Server) UpdateRules() error {
|
||||
db := database.DB.Model(new(Rule))
|
||||
defer s.rulesLock.Unlock()
|
||||
s.rulesLock.Lock()
|
||||
return errors.Wrap(db.Order("rank desc").Find(&s.rules).Error, "FTP update rules error")
|
||||
return errors.Wrap(db.Order("base_rank desc").Find(&s.rules).Error, "FTP update rules error")
|
||||
}
|
||||
|
||||
func getClientPasvConnAddress(ip, port string) string {
|
||||
@@ -359,9 +359,9 @@ func (s *Server) Run() {
|
||||
defer func() {
|
||||
if s.Enable {
|
||||
log.Error("FTP Server exited unexpectedly")
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
if err := s.UpdateRules(); err != nil {
|
||||
@@ -393,12 +393,13 @@ func (s *Server) Run() {
|
||||
if !s.Enable {
|
||||
_ = listener.Close()
|
||||
}
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
for s.Enable {
|
||||
for {
|
||||
tcpConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), net.ErrClosed.Error()) {
|
||||
if !errors.Is(err, net.ErrClosed) {
|
||||
log.Warn("FTP accept connection error: %v", err)
|
||||
} else {
|
||||
break
|
||||
|
||||
+36
-2
@@ -1,6 +1,7 @@
|
||||
package ftp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"github.com/li4n0/revsuit/internal/ipinfo"
|
||||
"github.com/li4n0/revsuit/internal/notice"
|
||||
"github.com/li4n0/revsuit/internal/record"
|
||||
"gorm.io/gorm"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
@@ -22,7 +24,7 @@ type Record struct {
|
||||
Path string `form:"path" json:"path"`
|
||||
Method Method `form:"method" json:"method"`
|
||||
Status Status `form:"status" json:"status"`
|
||||
File *file.FTPFile `form:"file" json:"file" notice:"-"`
|
||||
File *file.FTPFile `gorm:"foreignKey:RecordID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" form:"file" json:"file" notice:"-"`
|
||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||
}
|
||||
|
||||
@@ -50,10 +52,17 @@ func NewRecord(rule *Rule, flag, user, password, method, path, ip, area string,
|
||||
File: file,
|
||||
Rule: *rule,
|
||||
}
|
||||
|
||||
// sqlite db-level lock to prevent too much write operation lead to error of `database is locked` #54
|
||||
if database.Driver == database.Sqlite {
|
||||
database.Locker.Lock()
|
||||
defer database.Locker.Unlock()
|
||||
}
|
||||
|
||||
return r, database.DB.Create(r).Error
|
||||
}
|
||||
|
||||
func ListRecords(c *gin.Context) {
|
||||
func Records(c *gin.Context) {
|
||||
var (
|
||||
ftpRecord Record
|
||||
res []Record
|
||||
@@ -105,6 +114,31 @@ func ListRecords(c *gin.Context) {
|
||||
db.Where("rule_name = ?", ftpRecord.RuleName)
|
||||
}
|
||||
|
||||
//Delete records
|
||||
if c.Request.Method == http.MethodDelete {
|
||||
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if database.Driver == database.Sqlite {
|
||||
db.Exec("VACUUM")
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
})
|
||||
|
||||
log.Info("%d ftp records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
//List records
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
|
||||
+5
-15
@@ -43,7 +43,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
|
||||
[]string{
|
||||
"name",
|
||||
"flag_format",
|
||||
"rank",
|
||||
"base_rank",
|
||||
"pasv_address",
|
||||
"data",
|
||||
"push_to_client",
|
||||
@@ -96,10 +96,7 @@ func ListRules(c *gin.Context) {
|
||||
}
|
||||
|
||||
db := database.DB.Model(&ftpRule)
|
||||
if ftpRule.Name != "" {
|
||||
db.Where("name = ?", ftpRule.Name)
|
||||
}
|
||||
db.Count(&count)
|
||||
db.Where(&ftpRule).Count(&count)
|
||||
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
@@ -115,7 +112,7 @@ func ListRules(c *gin.Context) {
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
if err := db.Order("rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
if err := db.Order("base_rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
@@ -133,10 +130,7 @@ func ListRules(c *gin.Context) {
|
||||
|
||||
// UpsertRules creates or updates ftp rule from user submit
|
||||
func UpsertRules(c *gin.Context) {
|
||||
var (
|
||||
ftpRule Rule
|
||||
update bool
|
||||
)
|
||||
var ftpRule Rule
|
||||
|
||||
if err := c.ShouldBind(&ftpRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
@@ -147,10 +141,6 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if ftpRule.ID != 0 {
|
||||
update = true
|
||||
}
|
||||
|
||||
if err := ftpRule.CreateOrUpdate(); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
@@ -160,7 +150,7 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if update {
|
||||
if ftpRule.ID != 0 {
|
||||
log.Trace("FTP rule[id:%d] has been updated", ftpRule.ID)
|
||||
} else {
|
||||
log.Trace("FTP rule[id:%d] has been created", ftpRule.ID)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package ldap
|
||||
|
||||
type Config struct {
|
||||
Enable bool
|
||||
Addr string
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/li4n0/revsuit/internal/database"
|
||||
"github.com/li4n0/revsuit/internal/ipinfo"
|
||||
"github.com/li4n0/revsuit/internal/recycler"
|
||||
"github.com/pkg/errors"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Config
|
||||
rules []*Rule
|
||||
rulesLock sync.RWMutex
|
||||
livingLock sync.Mutex
|
||||
}
|
||||
|
||||
var (
|
||||
server *Server
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
func GetServer() *Server {
|
||||
once.Do(func() {
|
||||
server = &Server{rulesLock: sync.RWMutex{}, livingLock: sync.Mutex{}}
|
||||
})
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *Server) getRules() []*Rule {
|
||||
defer s.rulesLock.RUnlock()
|
||||
s.rulesLock.RLock()
|
||||
return s.rules
|
||||
}
|
||||
|
||||
func (s *Server) UpdateRules() error {
|
||||
db := database.DB.Model(new(Rule))
|
||||
defer s.rulesLock.Unlock()
|
||||
s.rulesLock.Lock()
|
||||
return errors.Wrap(db.Order("base_rank desc").Find(&s.rules).Error, "LDAP update rules error")
|
||||
}
|
||||
|
||||
func (s *Server) handleConnection(conn net.Conn) {
|
||||
defer func() {
|
||||
_ = conn.Close()
|
||||
if err := recover(); err != nil {
|
||||
recycler.Recycle(err)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := conn.SetDeadline(time.Now().Add(time.Second * 30)); err != nil {
|
||||
log.Warn("LDAP set connection deadline error:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
_, err := conn.Read(buf)
|
||||
if err != nil {
|
||||
log.Warn("LDAP read connection error:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !bytes.Contains(buf, []byte{
|
||||
0x30, 0x0c, 0x02, 0x01, 0x01, 0x60, 0x07,
|
||||
0x02, 0x01, 0x03, 0x04, 0x00, 0x80, 0x00}) {
|
||||
return
|
||||
}
|
||||
|
||||
send := []byte{
|
||||
0x30, 0x0c, 0x02, 0x01, 0x01, 0x61, 0x07,
|
||||
0x0a, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00,
|
||||
}
|
||||
_, err = conn.Write(send)
|
||||
if err != nil {
|
||||
log.Warn("LDAP write connection error: %v", err)
|
||||
return
|
||||
}
|
||||
_, err = conn.Read(buf)
|
||||
if err != nil {
|
||||
log.Warn("LDAP read connection error:%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
length := buf[8]
|
||||
pathBytes := bytes.Buffer{}
|
||||
for i := 1; i <= int(length); i++ {
|
||||
temp := []byte{buf[8+i]}
|
||||
pathBytes.Write(temp)
|
||||
}
|
||||
path := pathBytes.String()
|
||||
|
||||
for _, _rule := range s.getRules() {
|
||||
flag, flagGroup, _ := _rule.Match(path)
|
||||
if flag == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
area := ipinfo.Area(ip)
|
||||
|
||||
// create new record
|
||||
r, err := NewRecord(_rule, flag, path, ip, area)
|
||||
if err != nil {
|
||||
log.Warn("LDAP record[rule_id:%d] created failed :%s", _rule.ID, err)
|
||||
return
|
||||
}
|
||||
log.Info("LDAP record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
||||
|
||||
//only send to client when this connection recorded first time.
|
||||
if _rule.PushToClient {
|
||||
if flagGroup != "" {
|
||||
var count int64
|
||||
database.DB.Where("rule_name=? and path like ?", _rule.Name, "%"+flagGroup+"%").Model(&Record{}).Count(&count)
|
||||
if count <= 1 {
|
||||
r.PushToClient()
|
||||
log.Trace("LDAP record[id:%d, flagGroup:%s] has been put to client message queue", r.ID, flagGroup)
|
||||
}
|
||||
} else {
|
||||
r.PushToClient()
|
||||
log.Trace("LDAP record[id:%d, flag:%s] has been put to client message queue", r.ID, flag)
|
||||
}
|
||||
}
|
||||
|
||||
//send notice
|
||||
if _rule.Notice {
|
||||
go func() {
|
||||
r.Notice()
|
||||
log.Trace("LDAP record[id:%d] notice has been sent", r.ID)
|
||||
}()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Stop() {
|
||||
log.Info("LDAP Server is stopping...")
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
|
||||
func (s *Server) Restart() {
|
||||
s.Stop()
|
||||
time.Sleep(time.Second * 2)
|
||||
go s.Run()
|
||||
}
|
||||
|
||||
func (s *Server) Run() {
|
||||
s.Enable = true
|
||||
s.livingLock.Lock()
|
||||
defer func() {
|
||||
if s.Enable {
|
||||
log.Error("LDAP Server exited unexpectedly")
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
}()
|
||||
|
||||
if err := s.UpdateRules(); err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// run server
|
||||
log.Info("Starting LDAP Server at %v", s.Addr)
|
||||
|
||||
listener, err := net.Listen("tcp", s.Addr)
|
||||
if err != nil {
|
||||
log.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
s.livingLock.Lock()
|
||||
if !s.Enable {
|
||||
_ = listener.Close()
|
||||
}
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
for {
|
||||
tcpConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
if !errors.Is(err, net.ErrClosed) {
|
||||
log.Warn("LDAP accept connection error: %v", err)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
go s.handleConnection(tcpConn)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/li4n0/revsuit/internal/database"
|
||||
"github.com/li4n0/revsuit/internal/notice"
|
||||
"github.com/li4n0/revsuit/internal/record"
|
||||
"gorm.io/gorm"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
var _ record.Record = (*Record)(nil)
|
||||
|
||||
type Record struct {
|
||||
Path string `form:"path" json:"path"`
|
||||
record.BaseRecord
|
||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||
}
|
||||
|
||||
func (Record) TableName() string {
|
||||
return "ldap_records"
|
||||
}
|
||||
|
||||
func (r Record) Notice() {
|
||||
notice.Notice(r)
|
||||
}
|
||||
|
||||
func NewRecord(rule *Rule, flag, path, ip, area string) (r *Record, err error) {
|
||||
r = &Record{
|
||||
BaseRecord: record.BaseRecord{
|
||||
Flag: flag,
|
||||
RemoteIP: ip,
|
||||
IpArea: area,
|
||||
RequestTime: time.Now(),
|
||||
},
|
||||
Path: path,
|
||||
Rule: *rule,
|
||||
}
|
||||
|
||||
// sqlite db-level lock to prevent too much write operation lead to error of `database is locked` #54
|
||||
if database.Driver == database.Sqlite {
|
||||
database.Locker.Lock()
|
||||
defer database.Locker.Unlock()
|
||||
}
|
||||
|
||||
return r, database.DB.Create(r).Error
|
||||
}
|
||||
|
||||
func Records(c *gin.Context) {
|
||||
var (
|
||||
ldapRecord Record
|
||||
res []Record
|
||||
count int64
|
||||
order = c.Query("order")
|
||||
pageSize = 10
|
||||
)
|
||||
|
||||
if c.Query("pageSize") != "" {
|
||||
if n, err := strconv.Atoi(c.Query("pageSize")); err == nil {
|
||||
if n > 0 && n < 100 {
|
||||
pageSize = n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.ShouldBind(&ldapRecord); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
db := database.DB.Model(&ldapRecord)
|
||||
if ldapRecord.Flag != "" {
|
||||
db.Where("flag = ?", ldapRecord.Flag)
|
||||
}
|
||||
if ldapRecord.Path != "" {
|
||||
db.Where("path like ?", "%"+ldapRecord.Path+"%")
|
||||
}
|
||||
if ldapRecord.RemoteIP != "" {
|
||||
db.Where("remote_ip = ?", ldapRecord.RemoteIP)
|
||||
}
|
||||
if ldapRecord.RuleName != "" {
|
||||
db.Where("rule_name = ?", ldapRecord.RuleName)
|
||||
}
|
||||
|
||||
//Delete records
|
||||
if c.Request.Method == http.MethodDelete {
|
||||
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if database.Driver == database.Sqlite {
|
||||
db.Exec("VACUUM")
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
})
|
||||
|
||||
log.Info("%d ldap records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
//List records
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if order != "asc" {
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
if err := db.Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
"result": gin.H{"count": count, "data": res},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package ldap
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/li4n0/revsuit/internal/database"
|
||||
"github.com/li4n0/revsuit/internal/rule"
|
||||
"gorm.io/gorm/clause"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
// Rule LDAP rule struct
|
||||
type Rule struct {
|
||||
rule.BaseRule `yaml:",inline"`
|
||||
}
|
||||
|
||||
func (Rule) TableName() string {
|
||||
return "ldap_rules"
|
||||
}
|
||||
|
||||
// NewRule new ldap rule struct
|
||||
func NewRule(name, flagFormat string, pushToClient, notice bool) *Rule {
|
||||
return &Rule{
|
||||
BaseRule: rule.BaseRule{
|
||||
Name: name,
|
||||
FlagFormat: flagFormat,
|
||||
PushToClient: pushToClient,
|
||||
Notice: notice,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates or updates the ldap rule in database and ruleSet
|
||||
func (r *Rule) CreateOrUpdate() (err error) {
|
||||
db := database.DB.Model(r)
|
||||
err = db.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
DoUpdates: clause.AssignmentColumns(
|
||||
[]string{
|
||||
"name",
|
||||
"flag_format",
|
||||
"base_rank",
|
||||
"push_to_client",
|
||||
"notice",
|
||||
}),
|
||||
}).Create(r).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = GetServer().UpdateRules()
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete deletes the ldap rule in database and ruleSet
|
||||
func (r *Rule) Delete() (err error) {
|
||||
db := database.DB.Model(r)
|
||||
err = db.Delete(r).Error
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = GetServer().UpdateRules()
|
||||
return err
|
||||
}
|
||||
|
||||
// ListRules lists all ldap rules those satisfy the filter
|
||||
func ListRules(c *gin.Context) {
|
||||
var (
|
||||
ldapRule Rule
|
||||
res []Rule
|
||||
count int64
|
||||
order = c.Query("order")
|
||||
pageSize = 10
|
||||
)
|
||||
|
||||
if c.Query("pageSize") != "" {
|
||||
if n, err := strconv.Atoi(c.Query("pageSize")); err == nil {
|
||||
if n > 0 && n < 100 {
|
||||
pageSize = n
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := c.ShouldBind(&ldapRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
db := database.DB.Model(&ldapRule)
|
||||
db.Where(&ldapRule).Count(&count)
|
||||
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if order != "asc" {
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
if err := db.Order("base_rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
"result": gin.H{"count": count, "data": res},
|
||||
})
|
||||
}
|
||||
|
||||
// UpsertRules creates or updates ldap rule from user submit
|
||||
func UpsertRules(c *gin.Context) {
|
||||
var ldapRule Rule
|
||||
|
||||
if err := c.ShouldBind(&ldapRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ldapRule.CreateOrUpdate(); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"result": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if ldapRule.ID != 0 {
|
||||
log.Trace("LDAP rule[id:%d] has been updated", ldapRule.ID)
|
||||
} else {
|
||||
log.Trace("LDAP rule[id:%d] has been created", ldapRule.ID)
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
"result": nil,
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteRules deletes ldap rule from user submit
|
||||
func DeleteRules(c *gin.Context) {
|
||||
var ldapRule Rule
|
||||
|
||||
if err := c.ShouldBind(&ldapRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if err := ldapRule.Delete(); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("LDAP rule[id:%d] has been deleted", ldapRule.ID)
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
"data": nil,
|
||||
})
|
||||
}
|
||||
+7
-5
@@ -52,7 +52,7 @@ func (s *Server) UpdateRules() error {
|
||||
db := database.DB.Model(new(Rule))
|
||||
defer s.rulesLock.Unlock()
|
||||
s.rulesLock.Lock()
|
||||
return errors.Wrap(db.Order("rank desc").Find(&s.rules).Error, "MySQL update rules error")
|
||||
return errors.Wrap(db.Order("base_rank desc").Find(&s.rules).Error, "MySQL update rules error")
|
||||
}
|
||||
|
||||
// NewConnection is part of the mysql.Handler interface.
|
||||
@@ -273,7 +273,7 @@ func (s *Server) Stop() {
|
||||
}
|
||||
|
||||
func (s *Server) Restart() {
|
||||
s.Enable = false
|
||||
s.Stop()
|
||||
time.Sleep(time.Second * 2)
|
||||
go s.Run()
|
||||
}
|
||||
@@ -284,9 +284,9 @@ func (s *Server) Run() {
|
||||
defer func() {
|
||||
if s.Enable {
|
||||
log.Error("MySQL Server exited unexpectedly")
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
s.Enable = false
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
if err := s.UpdateRules(); err != nil {
|
||||
log.Error(err.Error())
|
||||
@@ -302,13 +302,15 @@ func (s *Server) Run() {
|
||||
s.listener, err = vmysql.NewListener("tcp", s.Addr, authServer, s, s.VersionString, 0, 0)
|
||||
if err != nil {
|
||||
log.Error("New MySQL Server failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
|
||||
s.livingLock.Lock()
|
||||
if !s.Enable {
|
||||
s.listener.Close()
|
||||
}
|
||||
s.livingLock.Unlock()
|
||||
}()
|
||||
|
||||
s.listener.Accept()
|
||||
|
||||
+39
-2
@@ -1,6 +1,7 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -9,6 +10,8 @@ import (
|
||||
"github.com/li4n0/revsuit/internal/file"
|
||||
"github.com/li4n0/revsuit/internal/notice"
|
||||
"github.com/li4n0/revsuit/internal/record"
|
||||
"gorm.io/gorm"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
var _ record.Record = (*Record)(nil)
|
||||
@@ -20,7 +23,7 @@ type Record struct {
|
||||
Schema string `gorm:"index" form:"schema" json:"schema" notice:"schema"`
|
||||
ClientOS string `gorm:"index" form:"client_os" json:"client_os" notice:"client_os"`
|
||||
LoadLocalData bool `gorm:"index" form:"load_local_data" json:"load_local_data" notice:"load_local_data"`
|
||||
Files []file.MySQLFile `form:"-" json:"files" notice:"-"`
|
||||
Files []file.MySQLFile `gorm:"foreignKey:RecordID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" form:"-" json:"files" notice:"-" `
|
||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||
}
|
||||
|
||||
@@ -48,10 +51,17 @@ func newRecord(rule *Rule, flag, username, schema, clientName, clientOS, remoteI
|
||||
Files: files,
|
||||
Rule: *rule,
|
||||
}
|
||||
|
||||
// sqlite db-level lock to prevent too much write operation lead to error of `database is locked` #54
|
||||
if database.Driver == database.Sqlite {
|
||||
database.Locker.Lock()
|
||||
defer database.Locker.Unlock()
|
||||
}
|
||||
|
||||
return r, database.DB.Create(r).Error
|
||||
}
|
||||
|
||||
func ListRecords(c *gin.Context) {
|
||||
func Records(c *gin.Context) {
|
||||
var (
|
||||
mysqlRecord Record
|
||||
res []Record
|
||||
@@ -86,6 +96,9 @@ func ListRecords(c *gin.Context) {
|
||||
if mysqlRecord.RuleName != "" {
|
||||
db.Where("rule_name = ?", mysqlRecord.RuleName)
|
||||
}
|
||||
if mysqlRecord.Username != "" {
|
||||
db.Where("username = ?", mysqlRecord.Username)
|
||||
}
|
||||
if mysqlRecord.ClientOS != "" {
|
||||
db.Where("client_os like ?", "%"+mysqlRecord.ClientOS)
|
||||
}
|
||||
@@ -103,6 +116,30 @@ func ListRecords(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
//Delete records
|
||||
if c.Request.Method == http.MethodDelete {
|
||||
if err := db.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
"data": nil,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if database.Driver == database.Sqlite {
|
||||
db.Exec("VACUUM")
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
})
|
||||
log.Info("%d mysql records deleted by %s", db.RowsAffected, c.Request.RemoteAddr)
|
||||
return
|
||||
}
|
||||
|
||||
//List records
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
|
||||
+5
-15
@@ -30,7 +30,7 @@ func (r *Rule) CreateOrUpdate() (err error) {
|
||||
[]string{
|
||||
"name",
|
||||
"flag_format",
|
||||
"rank",
|
||||
"base_rank",
|
||||
"files",
|
||||
"exploit_jdbc_client",
|
||||
"payloads",
|
||||
@@ -84,10 +84,7 @@ func ListRules(c *gin.Context) {
|
||||
}
|
||||
|
||||
db := database.DB.Model(&mysqlRule)
|
||||
if mysqlRule.Name != "" {
|
||||
db.Where("name = ?", mysqlRule.Name)
|
||||
}
|
||||
db.Count(&count)
|
||||
db.Where(&mysqlRule).Count(&count)
|
||||
|
||||
page, err := strconv.Atoi(c.Query("page"))
|
||||
if err != nil {
|
||||
@@ -103,7 +100,7 @@ func ListRules(c *gin.Context) {
|
||||
order = "desc"
|
||||
}
|
||||
|
||||
if err := db.Order("rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
if err := db.Order("base_rank desc").Order("id" + " " + order).Count(&count).Offset((page - 1) * pageSize).Limit(pageSize).Find(&res).Error; err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
"error": err.Error(),
|
||||
@@ -121,10 +118,7 @@ func ListRules(c *gin.Context) {
|
||||
|
||||
// UpsertRules create or update mysql rule from user submit
|
||||
func UpsertRules(c *gin.Context) {
|
||||
var (
|
||||
mysqlRule Rule
|
||||
update bool
|
||||
)
|
||||
var mysqlRule Rule
|
||||
|
||||
if err := c.ShouldBind(&mysqlRule); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
@@ -135,10 +129,6 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if mysqlRule.ID != 0 {
|
||||
update = true
|
||||
}
|
||||
|
||||
if err := mysqlRule.CreateOrUpdate(); err != nil {
|
||||
c.JSON(400, gin.H{
|
||||
"status": "failed",
|
||||
@@ -148,7 +138,7 @@ func UpsertRules(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
if update {
|
||||
if mysqlRule.ID != 0 {
|
||||
log.Trace("MySQL rule[id:%d] has been updated", mysqlRule.ID)
|
||||
} else {
|
||||
log.Trace("MySQL rule[id:%d] has been created", mysqlRule.ID)
|
||||
|
||||
+14
-14
@@ -247,23 +247,23 @@ func (c *Conn) parseRow(data []byte, fields []*querypb.Field) ([]sqltypes.Value,
|
||||
//
|
||||
// 1. if the server closes the connection when no command is in flight:
|
||||
//
|
||||
// 1.1 unix: WriteComQuery will fail with a 'broken pipe', and we'll
|
||||
// return CRServerGone(2006).
|
||||
// 1.1 unix: WriteComQuery will fail with a 'broken pipe', and we'll
|
||||
// return CRServerGone(2006).
|
||||
//
|
||||
// 1.2 tcp: WriteComQuery will most likely work, but readComQueryResponse
|
||||
// will fail, and we'll return CRServerLost(2013).
|
||||
// 1.2 tcp: WriteComQuery will most likely work, but readComQueryResponse
|
||||
// will fail, and we'll return CRServerLost(2013).
|
||||
//
|
||||
// This is because closing a TCP socket on the server side sends
|
||||
// a FIN to the client (telling the client the server is done
|
||||
// writing), but on most platforms doesn't send a RST. So the
|
||||
// client has no idea it can't write. So it succeeds writing data, which
|
||||
// *then* triggers the server to send a RST back, received a bit
|
||||
// later. By then, the client has already started waiting for
|
||||
// the response, and will just return a CRServerLost(2013).
|
||||
// So CRServerGone(2006) will almost never be seen with TCP.
|
||||
// This is because closing a TCP socket on the server side sends
|
||||
// a FIN to the client (telling the client the server is done
|
||||
// writing), but on most platforms doesn't send a RST. So the
|
||||
// client has no idea it can't write. So it succeeds writing data, which
|
||||
// *then* triggers the server to send a RST back, received a bit
|
||||
// later. By then, the client has already started waiting for
|
||||
// the response, and will just return a CRServerLost(2013).
|
||||
// So CRServerGone(2006) will almost never be seen with TCP.
|
||||
//
|
||||
// 2. if the server closes the connection when a command is in flight,
|
||||
// readComQueryResponse will fail, and we'll return CRServerLost(2013).
|
||||
// 2. if the server closes the connection when a command is in flight,
|
||||
// readComQueryResponse will fail, and we'll return CRServerLost(2013).
|
||||
func (c *Conn) ExecuteFetch(query string, maxrows int, wantfields bool) (result *sqltypes.Result, err error) {
|
||||
result, _, err = c.ExecuteFetchMulti(query, maxrows, wantfields)
|
||||
return result, err
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user