mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-06-09 17:56:58 +00:00
Compare commits
135 Commits
26.0-dev2
...
29.0-dev10
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f8a5a3a29 | ||
|
|
7f4cb6dfd4 | ||
|
|
3b063c3bb5 | ||
|
|
b9f5475e3a | ||
|
|
346e904e77 | ||
|
|
c5471c501b | ||
|
|
1597321e24 | ||
|
|
a3111dee35 | ||
|
|
f37abfff88 | ||
|
|
817c17ad32 | ||
|
|
51658db0bd | ||
|
|
b2a4af8600 | ||
|
|
60e7890e23 | ||
|
|
f19c2f08c3 | ||
|
|
d8c0132a98 | ||
|
|
c5a36a494a | ||
|
|
a54cb917d0 | ||
|
|
30a85a4b92 | ||
|
|
cdbacff996 | ||
|
|
cf127c781c | ||
|
|
852a5ff045 | ||
|
|
371e513249 | ||
|
|
97cce32e3f | ||
|
|
d2e91b4ffa | ||
|
|
d5a42a66de | ||
|
|
f01962085a | ||
|
|
73f3e448cf | ||
|
|
58a17897cf | ||
|
|
cf3106f636 | ||
|
|
a553a1b683 | ||
|
|
2a6bbd66e6 | ||
|
|
5a4baa05ca | ||
|
|
4ec9b9b475 | ||
|
|
1e2288b9a8 | ||
|
|
74f58a88bf | ||
|
|
69ee8752d0 | ||
|
|
0ef16bd55a | ||
|
|
27fa0afb72 | ||
|
|
c98c99e488 | ||
|
|
2d838d7699 | ||
|
|
d5bb036939 | ||
|
|
87ef469e25 | ||
|
|
72df652f6b | ||
|
|
c67675c138 | ||
|
|
e8d2b7eb3c | ||
|
|
83722f1a02 | ||
|
|
de42de9d62 | ||
|
|
bb3ae1ef70 | ||
|
|
5dfa94d76e | ||
|
|
dfe63f2318 | ||
|
|
026745ac8e | ||
|
|
9cf64a43f5 | ||
|
|
5e07924aca | ||
|
|
77078e78d1 | ||
|
|
bf2362d836 | ||
|
|
1c11523d9d | ||
|
|
150a87413d | ||
|
|
f7221a7355 | ||
|
|
4197ec198c | ||
|
|
5484b7c491 | ||
|
|
041223b558 | ||
|
|
71c04d20ef | ||
|
|
8852bac77b | ||
|
|
59d21e19b7 | ||
|
|
884cb791fc | ||
|
|
727d75bccc | ||
|
|
cb332cedd4 | ||
|
|
391af95fb5 | ||
|
|
9e62eaf4de | ||
|
|
81e830dd18 | ||
|
|
88e3fba1ef | ||
|
|
a4066da5d7 | ||
|
|
b59c48528d | ||
|
|
24f1a07910 | ||
|
|
d9e88169ae | ||
|
|
abf24a2230 | ||
|
|
db427d91cc | ||
|
|
f99a0b435e | ||
|
|
9318388101 | ||
|
|
b03ff675dc | ||
|
|
7ff28d8f7a | ||
|
|
0865b6e3d1 | ||
|
|
a42a0cd0b9 | ||
|
|
145004fe43 | ||
|
|
0a4674ea7c | ||
|
|
f013b0f03c | ||
|
|
2c72c27bc9 | ||
|
|
98ca1b2840 | ||
|
|
0365b8971f | ||
|
|
0f77cf8ef9 | ||
|
|
ea678a4d8c | ||
|
|
5b53252033 | ||
|
|
bfa275d08d | ||
|
|
d987bb17d2 | ||
|
|
89946041a1 | ||
|
|
b919c93f28 | ||
|
|
eac751190d | ||
|
|
2bc2051a46 | ||
|
|
89ad4e0f3a | ||
|
|
72f4753620 | ||
|
|
4badaadcc1 | ||
|
|
3f01f20f0c | ||
|
|
1fbb00f8f0 | ||
|
|
da7d3590fc | ||
|
|
256006ca3e | ||
|
|
213528c619 | ||
|
|
8b47dba05d | ||
|
|
5e5d5de91a | ||
|
|
680ea71958 | ||
|
|
5fb5dbbbf5 | ||
|
|
b3fe448ff1 | ||
|
|
101a54e8da | ||
|
|
3308cab826 | ||
|
|
5fdd8288f4 | ||
|
|
4cb32b40e6 | ||
|
|
afa81c7ec2 | ||
|
|
e84c7d3310 | ||
|
|
7d0a90cb78 | ||
|
|
24f79922e9 | ||
|
|
c3995009ee | ||
|
|
6e9fe2986e | ||
|
|
603240fedb | ||
|
|
e61871a68e | ||
|
|
379af59f07 | ||
|
|
ef9afe31a4 | ||
|
|
dca636b0fd | ||
|
|
9b72cc7aa6 | ||
|
|
d3c023b3ba | ||
|
|
5f2a4deb19 | ||
|
|
91f290987e | ||
|
|
2f3215b71a | ||
|
|
2e87a01346 | ||
|
|
453003bf14 | ||
|
|
80ca377668 | ||
|
|
d21297bc9c |
18
.github/workflows/acceptance_tests.yml
vendored
18
.github/workflows/acceptance_tests.yml
vendored
@@ -8,19 +8,15 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'develop'
|
- 'develop'
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: mizu-acceptance-tests-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-acceptance-tests:
|
run-acceptance-tests:
|
||||||
name: Run acceptance tests
|
name: Run acceptance tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.16
|
- name: Set up Go 1.17
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '^1.16'
|
go-version: '^1.17'
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
@@ -28,6 +24,16 @@ jobs:
|
|||||||
- name: Setup acceptance test
|
- name: Setup acceptance test
|
||||||
run: source ./acceptanceTests/setup.sh
|
run: source ./acceptanceTests/setup.sh
|
||||||
|
|
||||||
|
- name: Create k8s users and change context
|
||||||
|
env:
|
||||||
|
USERNAME_UNRESTRICTED: user-with-clusterwide-access
|
||||||
|
USERNAME_RESTRICTED: user-with-restricted-access
|
||||||
|
run: |
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_UNRESTRICTED}"
|
||||||
|
./acceptanceTests/create_user.sh "${USERNAME_RESTRICTED}"
|
||||||
|
kubectl apply -f cli/cmd/permissionFiles/permissions-all-namespaces-tap.yaml
|
||||||
|
kubectl config use-context ${USERNAME_UNRESTRICTED}
|
||||||
|
|
||||||
- name: Test
|
- name: Test
|
||||||
run: make acceptance-test
|
run: make acceptance-test
|
||||||
|
|
||||||
|
|||||||
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -15,10 +15,10 @@ jobs:
|
|||||||
name: CLI executable build
|
name: CLI executable build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.16
|
- name: Set up Go 1.17
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.16'
|
go-version: '1.17'
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|||||||
7
.github/workflows/release.yml
vendored
7
.github/workflows/release.yml
vendored
@@ -58,6 +58,7 @@ jobs:
|
|||||||
up9inc/mizu
|
up9inc/mizu
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,${{ steps.versioning.outputs.version }}
|
type=raw,${{ steps.versioning.outputs.version }}
|
||||||
|
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=auto
|
latest=auto
|
||||||
prefix=
|
prefix=
|
||||||
@@ -143,6 +144,7 @@ jobs:
|
|||||||
${{ steps.base_image_step.outputs.image }}
|
${{ steps.base_image_step.outputs.image }}
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,${{ steps.versioning.outputs.version }}
|
type=raw,${{ steps.versioning.outputs.version }}
|
||||||
|
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
|
||||||
flavor: |
|
flavor: |
|
||||||
latest=auto
|
latest=auto
|
||||||
prefix=
|
prefix=
|
||||||
@@ -205,6 +207,7 @@ jobs:
|
|||||||
up9inc/mizu
|
up9inc/mizu
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,${{ steps.versioning.outputs.version }}
|
type=raw,${{ steps.versioning.outputs.version }}
|
||||||
|
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v1
|
||||||
@@ -229,10 +232,10 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [docker-manifest, gcp-registry]
|
needs: [docker-manifest, gcp-registry]
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.16
|
- name: Set up Go 1.17
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.16'
|
go-version: '1.17'
|
||||||
|
|
||||||
- name: Check out the repo
|
- name: Check out the repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|||||||
2
.github/workflows/static_code_analysis.yml
vendored
2
.github/workflows/static_code_analysis.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '^1.16'
|
go-version: '^1.17'
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
53
.github/workflows/test.yml
vendored
53
.github/workflows/test.yml
vendored
@@ -5,48 +5,53 @@ on:
|
|||||||
branches:
|
branches:
|
||||||
- 'develop'
|
- 'develop'
|
||||||
- 'main'
|
- 'main'
|
||||||
|
push: # needed to upload test coverage report to codecov
|
||||||
|
branches:
|
||||||
|
- 'develop'
|
||||||
|
- 'main'
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: mizu-tests-validation-${{ github.ref }}
|
group: mizu-tests-validation-${{ github.ref }}
|
||||||
cancel-in-progress: true
|
cancel-in-progress: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
run-tests-cli:
|
run-unit-tests:
|
||||||
name: CLI Tests
|
name: Unit Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.16
|
- name: Set up Go 1.17
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '^1.16'
|
go-version: '^1.17'
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Test
|
- name: Install libpcap
|
||||||
run: make test-cli
|
shell: bash
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
|
||||||
uses: codecov/codecov-action@v2
|
|
||||||
|
|
||||||
run-tests-agent:
|
|
||||||
name: Agent Tests
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Set up Go 1.16
|
|
||||||
uses: actions/setup-go@v2
|
|
||||||
with:
|
|
||||||
go-version: '^1.16'
|
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libpcap-dev
|
sudo apt-get install libpcap-dev
|
||||||
|
|
||||||
- name: Test
|
- id: 'auth'
|
||||||
|
uses: 'google-github-actions/auth@v0'
|
||||||
|
with:
|
||||||
|
credentials_json: '${{ secrets.GCR_JSON_KEY }}'
|
||||||
|
|
||||||
|
- name: 'Set up Cloud SDK'
|
||||||
|
uses: 'google-github-actions/setup-gcloud@v0'
|
||||||
|
|
||||||
|
- name: CLI Test
|
||||||
|
run: make test-cli
|
||||||
|
|
||||||
|
- name: Agent Test
|
||||||
run: make test-agent
|
run: make test-agent
|
||||||
|
|
||||||
|
- name: Shared Test
|
||||||
|
run: make test-shared
|
||||||
|
|
||||||
|
- name: Extensions Test
|
||||||
|
run: make test-extensions
|
||||||
|
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v2
|
uses: codecov/codecov-action@v2
|
||||||
|
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -30,7 +30,7 @@ build
|
|||||||
pprof/*
|
pprof/*
|
||||||
|
|
||||||
# Database Files
|
# Database Files
|
||||||
*.bin
|
*.db
|
||||||
*.gob
|
*.gob
|
||||||
|
|
||||||
# Nohup Files - https://man7.org/linux/man-pages/man1/nohup.1p.html
|
# Nohup Files - https://man7.org/linux/man-pages/man1/nohup.1p.html
|
||||||
@@ -44,3 +44,7 @@ cypress.env.json
|
|||||||
*/cypress/screenshots
|
*/cypress/screenshots
|
||||||
*/cypress/videos
|
*/cypress/videos
|
||||||
*/cypress/support
|
*/cypress/support
|
||||||
|
|
||||||
|
# Ignore test data in extensions
|
||||||
|
tap/extensions/*/bin
|
||||||
|
tap/extensions/*/expect
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ RUN npm run build
|
|||||||
RUN npm run build-ent
|
RUN npm run build-ent
|
||||||
|
|
||||||
### Base builder image for native builds architecture
|
### Base builder image for native builds architecture
|
||||||
FROM golang:1.16-alpine AS builder-native-base
|
FROM golang:1.17-alpine AS builder-native-base
|
||||||
ENV CGO_ENABLED=1 GOOS=linux
|
ENV CGO_ENABLED=1 GOOS=linux
|
||||||
RUN apk add libpcap-dev g++ perl-utils
|
RUN apk add libpcap-dev g++ perl-utils
|
||||||
|
|
||||||
@@ -78,8 +78,8 @@ RUN go build -ldflags="-extldflags=-static -s -w \
|
|||||||
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
|
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
|
||||||
|
|
||||||
# Download Basenine executable, verify the sha1sum
|
# Download Basenine executable, verify the sha1sum
|
||||||
ADD https://github.com/up9inc/basenine/releases/download/v0.4.13/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
ADD https://github.com/up9inc/basenine/releases/download/v0.5.1/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
|
||||||
ADD https://github.com/up9inc/basenine/releases/download/v0.4.13/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
ADD https://github.com/up9inc/basenine/releases/download/v0.5.1/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
|
||||||
RUN shasum -a 256 -c basenine_linux_${GOARCH}.sha256
|
RUN shasum -a 256 -c basenine_linux_${GOARCH}.sha256
|
||||||
RUN chmod +x ./basenine_linux_${GOARCH}
|
RUN chmod +x ./basenine_linux_${GOARCH}
|
||||||
RUN mv ./basenine_linux_${GOARCH} ./basenine
|
RUN mv ./basenine_linux_${GOARCH} ./basenine
|
||||||
|
|||||||
26
Makefile
26
Makefile
@@ -80,14 +80,32 @@ clean-agent: ## Clean agent.
|
|||||||
clean-cli: ## Clean CLI.
|
clean-cli: ## Clean CLI.
|
||||||
@(cd cli; make clean ; echo "CLI cleanup done" )
|
@(cd cli; make clean ; echo "CLI cleanup done" )
|
||||||
|
|
||||||
clean-docker:
|
clean-docker: ## Run clen docker
|
||||||
@(echo "DOCKER cleanup - NOT IMPLEMENTED YET " )
|
@(echo "DOCKER cleanup - NOT IMPLEMENTED YET " )
|
||||||
|
|
||||||
test-cli:
|
test-lint: ## Run lint on all modules
|
||||||
|
cd agent && golangci-lint run
|
||||||
|
cd shared && golangci-lint run
|
||||||
|
cd tap && golangci-lint run
|
||||||
|
cd cli && golangci-lint run
|
||||||
|
cd acceptanceTests && golangci-lint run
|
||||||
|
cd tap/api && golangci-lint run
|
||||||
|
cd tap/extensions/ && for D in */; do cd $$D && golangci-lint run && cd ..; done
|
||||||
|
|
||||||
|
test-cli: ## Run cli tests
|
||||||
@echo "running cli tests"; cd cli && $(MAKE) test
|
@echo "running cli tests"; cd cli && $(MAKE) test
|
||||||
|
|
||||||
test-agent:
|
test-agent: ## Run agent tests
|
||||||
@echo "running agent tests"; cd agent && $(MAKE) test
|
@echo "running agent tests"; cd agent && $(MAKE) test
|
||||||
|
|
||||||
acceptance-test:
|
test-shared: ## Run shared tests
|
||||||
|
@echo "running shared tests"; cd shared && $(MAKE) test
|
||||||
|
|
||||||
|
test-extensions: ## Run extensions tests
|
||||||
|
@echo "running http tests"; cd tap/extensions/http && $(MAKE) test
|
||||||
|
@echo "running redis tests"; cd tap/extensions/redis && $(MAKE) test
|
||||||
|
@echo "running kafka tests"; cd tap/extensions/kafka && $(MAKE) test
|
||||||
|
@echo "running amqp tests"; cd tap/extensions/amqp && $(MAKE) test
|
||||||
|
|
||||||
|
acceptance-test: ## Run acceptance tests
|
||||||
@echo "running acceptance tests"; cd acceptanceTests && $(MAKE) test
|
@echo "running acceptance tests"; cd acceptanceTests && $(MAKE) test
|
||||||
|
|||||||
@@ -8,10 +8,10 @@
|
|||||||
<img alt="GitHub Latest Release" src="https://img.shields.io/github/v/release/up9inc/mizu?logo=GitHub&style=flat-square">
|
<img alt="GitHub Latest Release" src="https://img.shields.io/github/v/release/up9inc/mizu?logo=GitHub&style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hub.docker.com/r/up9inc/mizu">
|
<a href="https://hub.docker.com/r/up9inc/mizu">
|
||||||
<img alt="Docker pulls" src="https://img.shields.io/docker/pulls/up9inc/mizu?color=%23099cec">
|
<img alt="Docker pulls" src="https://img.shields.io/docker/pulls/up9inc/mizu?color=%23099cec&logo=Docker&style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://hub.docker.com/r/up9inc/mizu">
|
<a href="https://hub.docker.com/r/up9inc/mizu">
|
||||||
<img alt="Image size" src="https://img.shields.io/docker/image-size/up9inc/mizu/latest">
|
<img alt="Image size" src="https://img.shields.io/docker/image-size/up9inc/mizu/latest?logo=Docker&style=flat-square">
|
||||||
</a>
|
</a>
|
||||||
<a href="https://join.slack.com/t/up9/shared_invite/zt-tfjnduli-QzlR8VV4Z1w3YnPIAJfhlQ">
|
<a href="https://join.slack.com/t/up9/shared_invite/zt-tfjnduli-QzlR8VV4Z1w3YnPIAJfhlQ">
|
||||||
<img alt="Slack" src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social">
|
<img alt="Slack" src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social">
|
||||||
|
|||||||
6
acceptanceTests/.snyk
Normal file
6
acceptanceTests/.snyk
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
|
||||||
|
version: v1.14.0
|
||||||
|
ignore:
|
||||||
|
SNYK-GOLANG-GITHUBCOMPKGSFTP-569475:
|
||||||
|
- '*':
|
||||||
|
reason: None Given
|
||||||
@@ -23,19 +23,19 @@ func TestConfigRegenerate(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configPath, configPathErr := getConfigPath()
|
configPath, configPathErr := GetConfigPath()
|
||||||
if configPathErr != nil {
|
if configPathErr != nil {
|
||||||
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configCmdArgs := getDefaultConfigCommandArgs()
|
configCmdArgs := GetDefaultConfigCommandArgs()
|
||||||
|
|
||||||
configCmdArgs = append(configCmdArgs, "-r")
|
configCmdArgs = append(configCmdArgs, "-r")
|
||||||
|
|
||||||
@@ -74,13 +74,13 @@ func TestConfigGuiPort(t *testing.T) {
|
|||||||
|
|
||||||
for _, guiPort := range tests {
|
for _, guiPort := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", guiPort), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", guiPort), func(t *testing.T) {
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configPath, configPathErr := getConfigPath()
|
configPath, configPathErr := GetConfigPath()
|
||||||
if configPathErr != nil {
|
if configPathErr != nil {
|
||||||
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
@@ -100,16 +100,16 @@ func TestConfigGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +123,9 @@ func TestConfigGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(guiPort)
|
apiServerUrl := GetApiServerUrl(guiPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -147,13 +147,13 @@ func TestConfigSetGuiPort(t *testing.T) {
|
|||||||
|
|
||||||
for _, guiPortStruct := range tests {
|
for _, guiPortStruct := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", guiPortStruct.SetGuiPort), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", guiPortStruct.SetGuiPort), func(t *testing.T) {
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configPath, configPathErr := getConfigPath()
|
configPath, configPathErr := GetConfigPath()
|
||||||
if configPathErr != nil {
|
if configPathErr != nil {
|
||||||
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
@@ -173,9 +173,9 @@ func TestConfigSetGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "--set", fmt.Sprintf("tap.gui-port=%v", guiPortStruct.SetGuiPort))
|
tapCmdArgs = append(tapCmdArgs, "--set", fmt.Sprintf("tap.gui-port=%v", guiPortStruct.SetGuiPort))
|
||||||
@@ -184,7 +184,7 @@ func TestConfigSetGuiPort(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +198,9 @@ func TestConfigSetGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(guiPortStruct.SetGuiPort)
|
apiServerUrl := GetApiServerUrl(guiPortStruct.SetGuiPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -222,13 +222,13 @@ func TestConfigFlagGuiPort(t *testing.T) {
|
|||||||
|
|
||||||
for _, guiPortStruct := range tests {
|
for _, guiPortStruct := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", guiPortStruct.FlagGuiPort), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", guiPortStruct.FlagGuiPort), func(t *testing.T) {
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
configPath, configPathErr := getConfigPath()
|
configPath, configPathErr := GetConfigPath()
|
||||||
if configPathErr != nil {
|
if configPathErr != nil {
|
||||||
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
t.Errorf("failed to get config path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
@@ -248,9 +248,9 @@ func TestConfigFlagGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "-p", fmt.Sprintf("%v", guiPortStruct.FlagGuiPort))
|
tapCmdArgs = append(tapCmdArgs, "-p", fmt.Sprintf("%v", guiPortStruct.FlagGuiPort))
|
||||||
@@ -259,7 +259,7 @@ func TestConfigFlagGuiPort(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,9 +273,9 @@ func TestConfigFlagGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(guiPortStruct.FlagGuiPort)
|
apiServerUrl := GetApiServerUrl(guiPortStruct.FlagGuiPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
37
acceptanceTests/create_user.sh
Executable file
37
acceptanceTests/create_user.sh
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Create a user in Minikube cluster "minikube"
|
||||||
|
# Create context for user
|
||||||
|
# Usage:
|
||||||
|
# ./create_user.sh <username>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
NEW_USERNAME=$1
|
||||||
|
CERT_DIR="${HOME}/certs"
|
||||||
|
KEY_FILE="${CERT_DIR}/${NEW_USERNAME}.key"
|
||||||
|
CRT_FILE="${CERT_DIR}/${NEW_USERNAME}.crt"
|
||||||
|
MINIKUBE_KEY_FILE="${HOME}/.minikube/ca.key"
|
||||||
|
MINIKUBE_CRT_FILE="${HOME}/.minikube/ca.crt"
|
||||||
|
DAYS=1
|
||||||
|
|
||||||
|
echo "Creating user and context for username \"${NEW_USERNAME}\" in Minikube cluster"
|
||||||
|
|
||||||
|
if ! command -v openssl &> /dev/null
|
||||||
|
then
|
||||||
|
echo "Installing openssl"
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install openssl
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating certificate for user \"${NEW_USERNAME}\""
|
||||||
|
mkdir -p ${CERT_DIR}
|
||||||
|
echo "Generating key \"${KEY_FILE}\""
|
||||||
|
openssl genrsa -out "${KEY_FILE}" 2048
|
||||||
|
echo "Generating crt \"${CRT_FILE}\""
|
||||||
|
openssl req -new -key "${KEY_FILE}" -out "${CRT_FILE}" -subj "/CN=${NEW_USERNAME}/O=group1"
|
||||||
|
openssl x509 -req -in "${CRT_FILE}" -CA "${MINIKUBE_CRT_FILE}" -CAkey "${MINIKUBE_KEY_FILE}" -CAcreateserial -out "${CRT_FILE}" -days $DAYS
|
||||||
|
|
||||||
|
echo "Creating context for user \"${NEW_USERNAME}\""
|
||||||
|
kubectl config set-credentials "${NEW_USERNAME}" --client-certificate="${CRT_FILE}" --client-key="${KEY_FILE}"
|
||||||
|
kubectl config set-context "${NEW_USERNAME}" --cluster=minikube --user="${NEW_USERNAME}"
|
||||||
@@ -13,7 +13,10 @@
|
|||||||
"tests/Regex.js",
|
"tests/Regex.js",
|
||||||
"tests/RegexMasking.js",
|
"tests/RegexMasking.js",
|
||||||
"tests/IgnoredUserAgents.js",
|
"tests/IgnoredUserAgents.js",
|
||||||
"tests/UiTest.js"
|
"tests/UiTest.js",
|
||||||
|
"tests/Redis.js",
|
||||||
|
"tests/Rabbit.js",
|
||||||
|
"tests/serviceMapFunction.js"
|
||||||
],
|
],
|
||||||
|
|
||||||
"env": {
|
"env": {
|
||||||
@@ -21,6 +24,11 @@
|
|||||||
"redactHeaderContent": "User-Header[REDACTED]",
|
"redactHeaderContent": "User-Header[REDACTED]",
|
||||||
"redactBodyContent": "{ \"User\": \"[REDACTED]\" }",
|
"redactBodyContent": "{ \"User\": \"[REDACTED]\" }",
|
||||||
"regexMaskingBodyContent": "[REDACTED]",
|
"regexMaskingBodyContent": "[REDACTED]",
|
||||||
"minimumEntries": 25
|
"greenFilterColor": "rgb(210, 250, 210)",
|
||||||
|
"redFilterColor": "rgb(250, 214, 220)",
|
||||||
|
"bodyJsonClass": ".hljs",
|
||||||
|
"mizuWidth": 1920,
|
||||||
|
"normalMizuHeight": 1080,
|
||||||
|
"hugeMizuHeight": 3500
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
export const valueTabs = {
|
||||||
|
response: 'RESPONSE',
|
||||||
|
request: 'REQUEST',
|
||||||
|
none: null
|
||||||
|
}
|
||||||
|
|
||||||
|
const maxEntriesInDom = 13;
|
||||||
|
|
||||||
export function isValueExistsInElement(shouldInclude, content, domPathToContainer){
|
export function isValueExistsInElement(shouldInclude, content, domPathToContainer){
|
||||||
it(`should ${shouldInclude ? '' : 'not'} include '${content}'`, function () {
|
it(`should ${shouldInclude ? '' : 'not'} include '${content}'`, function () {
|
||||||
cy.get(domPathToContainer).then(htmlText => {
|
cy.get(domPathToContainer).then(htmlText => {
|
||||||
@@ -9,22 +17,171 @@ export function isValueExistsInElement(shouldInclude, content, domPathToContaine
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function resizeToHugeMizu() {
|
export function resizeToHugeMizu() {
|
||||||
cy.viewport(1920, 3500);
|
cy.viewport(Cypress.env('mizuWidth'), Cypress.env('hugeMizuHeight'));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resizeToNormalMizu() {
|
export function resizeToNormalMizu() {
|
||||||
cy.viewport(1920, 1080);
|
cy.viewport(Cypress.env('mizuWidth'), Cypress.env('normalMizuHeight'));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifyMinimumEntries() {
|
export function verifyMinimumEntries() {
|
||||||
const minimumEntries = Cypress.env('minimumEntries');
|
const entriesSent = Cypress.env('entriesCount');
|
||||||
it(`Making sure that mizu shows at least ${minimumEntries} entries`, async function () {
|
const minimumEntries = Math.round((0.75 * entriesSent));
|
||||||
|
|
||||||
|
it(`Making sure that mizu shows at least ${minimumEntries} entries`, function () {
|
||||||
cy.get('#total-entries').then(number => {
|
cy.get('#total-entries').then(number => {
|
||||||
const getNum = () => {
|
const getNum = () => {
|
||||||
const numOfEntries = number.text();
|
return parseInt(number.text());
|
||||||
return parseInt(numOfEntries);
|
|
||||||
};
|
};
|
||||||
cy.wrap({ there: getNum }).invoke('there').should('be.gte', minimumEntries);
|
|
||||||
|
cy.wrap({num: getNum}).invoke('num').should('be.gt', minimumEntries);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function leftTextCheck(entryNum, path, expectedText) {
|
||||||
|
cy.get(`#list #entry-${entryNum} ${path}`).invoke('text').should('eq', expectedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function leftOnHoverCheck(entryNum, path, filterName) {
|
||||||
|
cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover');
|
||||||
|
cy.get(`#list #entry-${entryNum} .Queryable-Tooltip`).invoke('text').should('match', new RegExp(filterName));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rightTextCheck(path, expectedText) {
|
||||||
|
cy.get(`#rightSideContainer ${path}`).should('have.text', expectedText);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function rightOnHoverCheck(path, expectedText) {
|
||||||
|
cy.get(`#rightSideContainer ${path}`).trigger('mouseover');
|
||||||
|
cy.get(`#rightSideContainer .Queryable-Tooltip`).invoke('text').should('match', new RegExp(expectedText));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkThatAllEntriesShown() {
|
||||||
|
cy.get('#entries-length').then(number => {
|
||||||
|
if (number.text() === '1')
|
||||||
|
cy.get('[title="Fetch old records"]').click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function checkFilterByMethod(funcDict) {
|
||||||
|
const {protocol, method, summary, hugeMizu} = funcDict;
|
||||||
|
const summaryDict = getSummeryDict(summary);
|
||||||
|
const methodDict = getMethodDict(method);
|
||||||
|
const protocolDict = getProtocolDict(protocol.name, protocol.text);
|
||||||
|
|
||||||
|
it(`Testing the method: ${method}`, function () {
|
||||||
|
// applying filter
|
||||||
|
cy.get('.w-tc-editor-text').clear().type(`method == "${method}"`);
|
||||||
|
cy.get('[type="submit"]').click();
|
||||||
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
||||||
|
|
||||||
|
cy.get('#entries-length').then(number => {
|
||||||
|
// if the entries list isn't expanded it expands here
|
||||||
|
if (number.text() === '0' || number.text() === '1') // todo change when TRA-4262 is fixed
|
||||||
|
cy.get('[title="Fetch old records"]').click();
|
||||||
|
|
||||||
|
cy.get('#entries-length').should('not.have.text', '0').and('not.have.text', '1').then(() => {
|
||||||
|
cy.get(`#list [id]`).then(elements => {
|
||||||
|
const listElmWithIdAttr = Object.values(elements);
|
||||||
|
let doneCheckOnFirst = false;
|
||||||
|
|
||||||
|
cy.get('#entries-length').invoke('text').then(len => {
|
||||||
|
resizeIfNeeded(len);
|
||||||
|
listElmWithIdAttr.forEach(entry => {
|
||||||
|
if (entry?.id && entry.id.match(RegExp(/entry-(\d{2}|\d{1})$/gm))) {
|
||||||
|
const entryNum = getEntryNumById(entry.id);
|
||||||
|
|
||||||
|
leftTextCheck(entryNum, methodDict.pathLeft, methodDict.expectedText);
|
||||||
|
leftTextCheck(entryNum, protocolDict.pathLeft, protocolDict.expectedTextLeft);
|
||||||
|
if (summaryDict)
|
||||||
|
leftTextCheck(entryNum, summaryDict.pathLeft, summaryDict.expectedText);
|
||||||
|
|
||||||
|
if (!doneCheckOnFirst) {
|
||||||
|
deepCheck(funcDict, protocolDict, methodDict, entry);
|
||||||
|
doneCheckOnFirst = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resizeIfNeeded(len);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeIfNeeded(entriesLen) {
|
||||||
|
if (entriesLen > maxEntriesInDom){
|
||||||
|
Cypress.config().viewportHeight === Cypress.env('normalMizuHeight') ?
|
||||||
|
resizeToHugeMizu() : resizeToNormalMizu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deepCheck(generalDict, protocolDict, methodDict, entry) {
|
||||||
|
const entryNum = getEntryNumById(entry.id);
|
||||||
|
const {summary, value} = generalDict;
|
||||||
|
const summaryDict = getSummeryDict(summary);
|
||||||
|
|
||||||
|
leftOnHoverCheck(entryNum, methodDict.pathLeft, methodDict.expectedOnHover);
|
||||||
|
leftOnHoverCheck(entryNum, protocolDict.pathLeft, protocolDict.expectedOnHover);
|
||||||
|
if (summaryDict)
|
||||||
|
leftOnHoverCheck(entryNum, summaryDict.pathLeft, summaryDict.expectedOnHover);
|
||||||
|
|
||||||
|
cy.get(`#${entry.id}`).click();
|
||||||
|
|
||||||
|
rightTextCheck(methodDict.pathRight, methodDict.expectedText);
|
||||||
|
rightTextCheck(protocolDict.pathRight, protocolDict.expectedTextRight);
|
||||||
|
if (summaryDict)
|
||||||
|
rightTextCheck(summaryDict.pathRight, summaryDict.expectedText);
|
||||||
|
|
||||||
|
rightOnHoverCheck(methodDict.pathRight, methodDict.expectedOnHover);
|
||||||
|
rightOnHoverCheck(protocolDict.pathRight, protocolDict.expectedOnHover);
|
||||||
|
if (summaryDict)
|
||||||
|
rightOnHoverCheck(summaryDict.pathRight, summaryDict.expectedOnHover);
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
if (value.tab === valueTabs.response)
|
||||||
|
cy.contains('Response').click();
|
||||||
|
cy.get(Cypress.env('bodyJsonClass')).then(text => {
|
||||||
|
expect(text.text()).to.match(value.regex)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSummeryDict(summary) {
|
||||||
|
if (summary) {
|
||||||
|
return {
|
||||||
|
pathLeft: '> :nth-child(2) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
||||||
|
pathRight: '> :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(2) > :nth-child(2)',
|
||||||
|
expectedText: summary,
|
||||||
|
expectedOnHover: `summary == "${summary}"`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMethodDict(method) {
|
||||||
|
return {
|
||||||
|
pathLeft: '> :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
||||||
|
pathRight: '> :nth-child(2) > :nth-child(1) > :nth-child(1) > :nth-child(1) > :nth-child(2)',
|
||||||
|
expectedText: method,
|
||||||
|
expectedOnHover: `method == "${method}"`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProtocolDict(protocol, protocolText) {
|
||||||
|
return {
|
||||||
|
pathLeft: '> :nth-child(1) > :nth-child(1)',
|
||||||
|
pathRight: '> :nth-child(1) > :nth-child(1) > :nth-child(1) > :nth-child(1)',
|
||||||
|
expectedTextLeft: protocol.toUpperCase(),
|
||||||
|
expectedTextRight: protocolText,
|
||||||
|
expectedOnHover: protocol.toLowerCase()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEntryNumById (id) {
|
||||||
|
return parseInt(id.split('-')[1]);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
|
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
|
||||||
import {verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
|
||||||
|
|
||||||
it('check', function () {
|
it('check', function () {
|
||||||
const podName = Cypress.env('name'), namespace = Cypress.env('namespace');
|
const podName = Cypress.env('name'), namespace = Cypress.env('namespace');
|
||||||
@@ -9,8 +8,6 @@ it('check', function () {
|
|||||||
cy.visit(`http://localhost:${port}`);
|
cy.visit(`http://localhost:${port}`);
|
||||||
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
|
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
|
||||||
|
|
||||||
verifyMinimumEntries();
|
|
||||||
|
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get('.podsCount').trigger('mouseover');
|
||||||
findLineAndCheck(getExpectedDetailsDict(podName, namespace));
|
findLineAndCheck(getExpectedDetailsDict(podName, namespace));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import {isValueExistsInElement, resizeToHugeMizu, verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
import {
|
||||||
|
checkThatAllEntriesShown,
|
||||||
|
isValueExistsInElement,
|
||||||
|
resizeToHugeMizu,
|
||||||
|
} from "../testHelpers/TrafficHelper";
|
||||||
|
|
||||||
it('Loading Mizu', function () {
|
it('Loading Mizu', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
});
|
});
|
||||||
|
|
||||||
verifyMinimumEntries();
|
|
||||||
|
|
||||||
checkEntries();
|
checkEntries();
|
||||||
|
|
||||||
function checkEntries() {
|
function checkEntries() {
|
||||||
@@ -20,13 +22,6 @@ function checkEntries() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkThatAllEntriesShown() {
|
|
||||||
cy.get('#entries-length').then(number => {
|
|
||||||
if (number.text() === '1')
|
|
||||||
cy.get('[title="Fetch old records"]').click();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkEntry(entryIndex) {
|
function checkEntry(entryIndex) {
|
||||||
cy.get(`#entry-${entryIndex}`).click();
|
cy.get(`#entry-${entryIndex}`).click();
|
||||||
cy.get('#tbody-Headers').should('be.visible');
|
cy.get('#tbody-Headers').should('be.visible');
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper';
|
import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
|
||||||
|
|
||||||
it('Loading Mizu', function () {
|
it('Loading Mizu', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
});
|
});
|
||||||
|
|
||||||
verifyMinimumEntries();
|
|
||||||
|
|
||||||
isValueExistsInElement(false, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
isValueExistsInElement(false, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
||||||
isValueExistsInElement(false, Cypress.env('redactBodyContent'), '.hljs');
|
isValueExistsInElement(false, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));
|
||||||
|
|||||||
49
acceptanceTests/cypress/integration/tests/Rabbit.js
Normal file
49
acceptanceTests/cypress/integration/tests/Rabbit.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import {checkFilterByMethod, valueTabs,} from "../testHelpers/TrafficHelper";
|
||||||
|
|
||||||
|
it('opening mizu', function () {
|
||||||
|
cy.visit(Cypress.env('testUrl'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const rabbitProtocolDetails = {name: 'AMQP', text: 'Advanced Message Queuing Protocol 0-9-1'};
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'exchange declare',
|
||||||
|
summary: 'exchange',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'queue declare',
|
||||||
|
summary: 'queue',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'queue bind',
|
||||||
|
summary: 'queue',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'basic publish',
|
||||||
|
summary: 'exchange',
|
||||||
|
value: {tab: valueTabs.request, regex: /^message$/mg}
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'basic consume',
|
||||||
|
summary: 'queue',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: rabbitProtocolDetails,
|
||||||
|
method: 'basic deliver',
|
||||||
|
summary: 'exchange',
|
||||||
|
value: {tab: valueTabs.request, regex: /^message$/mg}
|
||||||
|
});
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper';
|
import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
|
||||||
|
|
||||||
it('Loading Mizu', function () {
|
it('Loading Mizu', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
});
|
});
|
||||||
|
|
||||||
verifyMinimumEntries();
|
|
||||||
|
|
||||||
isValueExistsInElement(true, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
isValueExistsInElement(true, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
||||||
isValueExistsInElement(true, Cypress.env('redactBodyContent'), '.hljs');
|
isValueExistsInElement(true, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));
|
||||||
|
|||||||
42
acceptanceTests/cypress/integration/tests/Redis.js
Normal file
42
acceptanceTests/cypress/integration/tests/Redis.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import {checkFilterByMethod, valueTabs,} from "../testHelpers/TrafficHelper";
|
||||||
|
|
||||||
|
it('opening mizu', function () {
|
||||||
|
cy.visit(Cypress.env('testUrl'));
|
||||||
|
});
|
||||||
|
|
||||||
|
const redisProtocolDetails = {name: 'redis', text: 'Redis Serialization Protocol'};
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: redisProtocolDetails,
|
||||||
|
method: 'PING',
|
||||||
|
summary: null,
|
||||||
|
value: null
|
||||||
|
})
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: redisProtocolDetails,
|
||||||
|
method: 'SET',
|
||||||
|
summary: 'key',
|
||||||
|
value: {tab: valueTabs.request, regex: /^\[value, keepttl]$/mg}
|
||||||
|
})
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: redisProtocolDetails,
|
||||||
|
method: 'EXISTS',
|
||||||
|
summary: 'key',
|
||||||
|
value: {tab: valueTabs.response, regex: /^1$/mg}
|
||||||
|
})
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: redisProtocolDetails,
|
||||||
|
method: 'GET',
|
||||||
|
summary: 'key',
|
||||||
|
value: {tab: valueTabs.response, regex: /^value$/mg}
|
||||||
|
})
|
||||||
|
|
||||||
|
checkFilterByMethod({
|
||||||
|
protocol: redisProtocolDetails,
|
||||||
|
method: 'DEL',
|
||||||
|
summary: 'key',
|
||||||
|
value: {tab: valueTabs.response, regex: /^1$|^0$/mg}
|
||||||
|
})
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
import {isValueExistsInElement, verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
import {isValueExistsInElement} from "../testHelpers/TrafficHelper";
|
||||||
|
|
||||||
it('Loading Mizu', function () {
|
it('Loading Mizu', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
});
|
});
|
||||||
|
|
||||||
verifyMinimumEntries();
|
isValueExistsInElement(true, Cypress.env('regexMaskingBodyContent'), Cypress.env('bodyJsonClass'));
|
||||||
|
|
||||||
isValueExistsInElement(true, Cypress.env('regexMaskingBodyContent'), '.hljs');
|
|
||||||
|
|||||||
@@ -1,9 +1,23 @@
|
|||||||
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
|
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
|
||||||
import {resizeToHugeMizu, resizeToNormalMizu, verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
import {
|
||||||
const greenFilterColor = 'rgb(210, 250, 210)';
|
leftOnHoverCheck,
|
||||||
const redFilterColor = 'rgb(250, 214, 220)';
|
leftTextCheck,
|
||||||
|
resizeToHugeMizu,
|
||||||
|
resizeToNormalMizu,
|
||||||
|
rightOnHoverCheck,
|
||||||
|
rightTextCheck,
|
||||||
|
verifyMinimumEntries
|
||||||
|
} from "../testHelpers/TrafficHelper";
|
||||||
|
|
||||||
const refreshWaitTimeout = 10000;
|
const refreshWaitTimeout = 10000;
|
||||||
const bodyJsonClass = '.hljs';
|
|
||||||
|
|
||||||
|
const fullParam = Cypress.env('arrayDict'); // "Name:fooNamespace:barName:foo1Namespace:bar1"
|
||||||
|
const podsArray = fullParam.split('Name:').slice(1); // ["fooNamespace:bar", "foo1Namespace:bar1"]
|
||||||
|
podsArray.forEach((podStr, index) => {
|
||||||
|
const podAndNamespaceArr = podStr.split('Namespace:'); // [foo, bar] / [foo1, bar1]
|
||||||
|
podsArray[index] = getExpectedDetailsDict(podAndNamespaceArr[0], podAndNamespaceArr[1]);
|
||||||
|
});
|
||||||
|
|
||||||
it('opening mizu', function () {
|
it('opening mizu', function () {
|
||||||
cy.visit(Cypress.env('testUrl'));
|
cy.visit(Cypress.env('testUrl'));
|
||||||
@@ -12,16 +26,13 @@ it('opening mizu', function () {
|
|||||||
verifyMinimumEntries();
|
verifyMinimumEntries();
|
||||||
|
|
||||||
it('top bar check', function () {
|
it('top bar check', function () {
|
||||||
const podName1 = 'httpbin', namespace1 = 'mizu-tests';
|
|
||||||
const podName2 = 'httpbin2', namespace2 = 'mizu-tests';
|
|
||||||
|
|
||||||
cy.get('.podsCount').trigger('mouseover');
|
cy.get('.podsCount').trigger('mouseover');
|
||||||
findLineAndCheck(getExpectedDetailsDict(podName1, namespace1));
|
podsArray.map(findLineAndCheck);
|
||||||
findLineAndCheck(getExpectedDetailsDict(podName2, namespace2));
|
|
||||||
cy.reload();
|
cy.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('filtering guide check', function () {
|
it('filtering guide check', function () {
|
||||||
|
cy.reload();
|
||||||
cy.get('[title="Open Filtering Guide (Cheatsheet)"]').click();
|
cy.get('[title="Open Filtering Guide (Cheatsheet)"]').click();
|
||||||
cy.get('#modal-modal-title').should('be.visible');
|
cy.get('#modal-modal-title').should('be.visible');
|
||||||
cy.get('[lang="en"]').click(0, 0);
|
cy.get('[lang="en"]').click(0, 0);
|
||||||
@@ -79,14 +90,27 @@ checkFilter({
|
|||||||
applyByEnter: false
|
applyByEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
if (Cypress.env('shouldCheckSrcAndDest')) {
|
||||||
name: 'src.name == ""',
|
serviceMapCheck();
|
||||||
leftSidePath: '[title="Source Name"]',
|
|
||||||
leftSideExpectedText: '[Unresolved]',
|
checkFilter({
|
||||||
rightSidePath: '> :nth-child(2) [title="Source Name"]',
|
name: 'src.name == ""',
|
||||||
rightSideExpectedText: '[Unresolved]',
|
leftSidePath: '[title="Source Name"]',
|
||||||
applyByEnter: false
|
leftSideExpectedText: '[Unresolved]',
|
||||||
});
|
rightSidePath: '> :nth-child(2) [title="Source Name"]',
|
||||||
|
rightSideExpectedText: '[Unresolved]',
|
||||||
|
applyByEnter: false
|
||||||
|
});
|
||||||
|
|
||||||
|
checkFilter({
|
||||||
|
name: `dst.name == "httpbin.mizu-tests"`,
|
||||||
|
leftSidePath: '> :nth-child(3) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
||||||
|
leftSideExpectedText: 'httpbin.mizu-tests',
|
||||||
|
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
||||||
|
rightSideExpectedText: 'httpbin.mizu-tests',
|
||||||
|
applyByEnter: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'method == "GET"',
|
name: 'method == "GET"',
|
||||||
@@ -106,15 +130,6 @@ checkFilter({
|
|||||||
applyByEnter: false
|
applyByEnter: false
|
||||||
});
|
});
|
||||||
|
|
||||||
checkFilter({
|
|
||||||
name: 'dst.name == "httpbin.mizu-tests"',
|
|
||||||
leftSidePath: '> :nth-child(3) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
|
||||||
leftSideExpectedText: 'httpbin.mizu-tests',
|
|
||||||
rightSidePath: '> :nth-child(2) > :nth-child(2) > :nth-child(2) > :nth-child(3) > :nth-child(2)',
|
|
||||||
rightSideExpectedText: 'httpbin.mizu-tests',
|
|
||||||
applyByEnter: false
|
|
||||||
});
|
|
||||||
|
|
||||||
checkFilter({
|
checkFilter({
|
||||||
name: 'src.ip == "127.0.0.1"',
|
name: 'src.ip == "127.0.0.1"',
|
||||||
leftSidePath: '[title="Source IP"]',
|
leftSidePath: '[title="Source IP"]',
|
||||||
@@ -133,7 +148,7 @@ function checkFilterNoResults(filterName) {
|
|||||||
|
|
||||||
// applying the filter
|
// applying the filter
|
||||||
cy.get('.w-tc-editor-text').type(filterName);
|
cy.get('.w-tc-editor-text').type(filterName);
|
||||||
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', greenFilterColor);
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
||||||
cy.get('[type="submit"]').click();
|
cy.get('[type="submit"]').click();
|
||||||
|
|
||||||
// waiting for the entries number to load
|
// waiting for the entries number to load
|
||||||
@@ -162,11 +177,12 @@ function shouldNotExist(entryNum) {
|
|||||||
|
|
||||||
function checkIllegalFilter(illegalFilterName) {
|
function checkIllegalFilter(illegalFilterName) {
|
||||||
it(`should show red search bar with the input: ${illegalFilterName}`, function () {
|
it(`should show red search bar with the input: ${illegalFilterName}`, function () {
|
||||||
|
cy.reload();
|
||||||
cy.get('#total-entries').then(number => {
|
cy.get('#total-entries').then(number => {
|
||||||
const totalEntries = number.text();
|
const totalEntries = number.text();
|
||||||
|
|
||||||
cy.get('.w-tc-editor-text').type(illegalFilterName);
|
cy.get('.w-tc-editor-text').type(illegalFilterName);
|
||||||
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', redFilterColor);
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('redFilterColor'));
|
||||||
cy.get('[type="submit"]').click();
|
cy.get('[type="submit"]').click();
|
||||||
|
|
||||||
cy.get('[role="alert"]').should('be.visible');
|
cy.get('[role="alert"]').should('be.visible');
|
||||||
@@ -183,7 +199,7 @@ function checkFilter(filterDetails){
|
|||||||
const entriesForDeeperCheck = 5;
|
const entriesForDeeperCheck = 5;
|
||||||
|
|
||||||
it(`checking the filter: ${name}`, function () {
|
it(`checking the filter: ${name}`, function () {
|
||||||
cy.get('#total-entries').then(number => {
|
cy.get('#total-entries').should('not.have.text', '0').then(number => {
|
||||||
const totalEntries = number.text();
|
const totalEntries = number.text();
|
||||||
|
|
||||||
// checks the hover on the last entry (the only one in DOM at the beginning)
|
// checks the hover on the last entry (the only one in DOM at the beginning)
|
||||||
@@ -191,7 +207,7 @@ function checkFilter(filterDetails){
|
|||||||
|
|
||||||
// applying the filter with alt+enter or with the button
|
// applying the filter with alt+enter or with the button
|
||||||
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
|
cy.get('.w-tc-editor-text').type(`${name}${applyByEnter ? '{alt+enter}' : ''}`);
|
||||||
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', greenFilterColor);
|
cy.get('.w-tc-editor').should('have.attr', 'style').and('include', Cypress.env('greenFilterColor'));
|
||||||
if (!applyByEnter)
|
if (!applyByEnter)
|
||||||
cy.get('[type="submit"]').click();
|
cy.get('[type="submit"]').click();
|
||||||
|
|
||||||
@@ -234,30 +250,11 @@ function deeperChcek(leftSidePath, rightSidePath, filterName, leftSideExpectedTe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function leftTextCheck(entryNum, path, expectedText) {
|
|
||||||
cy.get(`#list #entry-${entryNum} ${path}`).invoke('text').should('eq', expectedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
function leftOnHoverCheck(entryNum, path, filterName) {
|
|
||||||
cy.get(`#list #entry-${entryNum} ${path}`).trigger('mouseover');
|
|
||||||
cy.get(`#list #entry-${entryNum} .Queryable-Tooltip`).should('have.text', filterName);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rightTextCheck(path, expectedText) {
|
|
||||||
cy.get(`.TrafficPage-Container > :nth-child(2) ${path}`).should('have.text', expectedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
function rightOnHoverCheck(path, expectedText) {
|
|
||||||
cy.get(`.TrafficPage-Container > :nth-child(2) ${path}`).trigger('mouseover');
|
|
||||||
cy.get(`.TrafficPage-Container > :nth-child(2) .Queryable-Tooltip`).should('have.text', expectedText);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function checkRightSideResponseBody() {
|
function checkRightSideResponseBody() {
|
||||||
cy.contains('Response').click();
|
cy.contains('Response').click();
|
||||||
clickCheckbox('Decode Base64');
|
clickCheckbox('Decode Base64');
|
||||||
|
|
||||||
cy.get(`${bodyJsonClass}`).then(value => {
|
cy.get(`${Cypress.env('bodyJsonClass')}`).then(value => {
|
||||||
const encodedBody = value.text();
|
const encodedBody = value.text();
|
||||||
const decodedBody = atob(encodedBody);
|
const decodedBody = atob(encodedBody);
|
||||||
const responseBody = JSON.parse(decodedBody);
|
const responseBody = JSON.parse(decodedBody);
|
||||||
@@ -278,11 +275,11 @@ function checkRightSideResponseBody() {
|
|||||||
expect(responseBody.headers['Accept-Encoding']).to.match(expectdJsonBody.headers['Accept-Encoding']);
|
expect(responseBody.headers['Accept-Encoding']).to.match(expectdJsonBody.headers['Accept-Encoding']);
|
||||||
expect(responseBody.headers['X-Forwarded-Uri']).to.match(expectdJsonBody.headers['X-Forwarded-Uri']);
|
expect(responseBody.headers['X-Forwarded-Uri']).to.match(expectdJsonBody.headers['X-Forwarded-Uri']);
|
||||||
|
|
||||||
cy.get(`${bodyJsonClass}`).should('have.text', encodedBody);
|
cy.get(`${Cypress.env('bodyJsonClass')}`).should('have.text', encodedBody);
|
||||||
clickCheckbox('Decode Base64');
|
clickCheckbox('Decode Base64');
|
||||||
|
|
||||||
cy.get(`${bodyJsonClass} > `).its('length').should('be.gt', 1).then(linesNum => {
|
cy.get(`${Cypress.env('bodyJsonClass')} > `).its('length').should('be.gt', 1).then(linesNum => {
|
||||||
cy.get(`${bodyJsonClass} > >`).its('length').should('be.gt', linesNum).then(jsonItemsNum => {
|
cy.get(`${Cypress.env('bodyJsonClass')} > >`).its('length').should('be.gt', linesNum).then(jsonItemsNum => {
|
||||||
checkPrettyAndLineNums(jsonItemsNum, decodedBody);
|
checkPrettyAndLineNums(jsonItemsNum, decodedBody);
|
||||||
|
|
||||||
clickCheckbox('Line numbers');
|
clickCheckbox('Line numbers');
|
||||||
@@ -304,7 +301,7 @@ function clickCheckbox(type) {
|
|||||||
|
|
||||||
function checkPrettyAndLineNums(jsonItemsLen, decodedBody) {
|
function checkPrettyAndLineNums(jsonItemsLen, decodedBody) {
|
||||||
decodedBody = decodedBody.replaceAll(' ', '');
|
decodedBody = decodedBody.replaceAll(' ', '');
|
||||||
cy.get(`${bodyJsonClass} >`).then(elements => {
|
cy.get(`${Cypress.env('bodyJsonClass')} >`).then(elements => {
|
||||||
const lines = Object.values(elements);
|
const lines = Object.values(elements);
|
||||||
lines.forEach((line, index) => {
|
lines.forEach((line, index) => {
|
||||||
if (line.getAttribute) {
|
if (line.getAttribute) {
|
||||||
@@ -324,13 +321,52 @@ function getCleanLine(lineElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkPrettyOrNothing(jsonItems, decodedBody) {
|
function checkPrettyOrNothing(jsonItems, decodedBody) {
|
||||||
cy.get(`${bodyJsonClass} > `).should('have.length', jsonItems).then(text => {
|
cy.get(`${Cypress.env('bodyJsonClass')} > `).should('have.length', jsonItems).then(text => {
|
||||||
const json = text.text();
|
const json = text.text();
|
||||||
expect(json).to.equal(decodedBody);
|
expect(json).to.equal(decodedBody);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkOnlyLineNumberes(jsonItems, decodedText) {
|
function checkOnlyLineNumberes(jsonItems, decodedText) {
|
||||||
cy.get(`${bodyJsonClass} >`).should('have.length', 1).and('have.text', decodedText);
|
cy.get(`${Cypress.env('bodyJsonClass')} >`).should('have.length', 1).and('have.text', decodedText);
|
||||||
cy.get(`${bodyJsonClass} > >`).should('have.length', jsonItems)
|
cy.get(`${Cypress.env('bodyJsonClass')} > >`).should('have.length', jsonItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
function serviceMapCheck() {
|
||||||
|
it('service map test', function () {
|
||||||
|
cy.intercept(`${Cypress.env('testUrl')}/servicemap/get`).as('serviceMapRequest');
|
||||||
|
cy.get('#total-entries').should('not.have.text', '0').then(() => {
|
||||||
|
cy.get('#total-entries').invoke('text').then(entriesNum => {
|
||||||
|
cy.get('[alt="service-map"]').click();
|
||||||
|
cy.wait('@serviceMapRequest').then(({response}) => {
|
||||||
|
const body = response.body;
|
||||||
|
const nodeParams = {
|
||||||
|
destination: 'httpbin.mizu-tests',
|
||||||
|
source: '127.0.0.1'
|
||||||
|
};
|
||||||
|
serviceMapAPICheck(body, parseInt(entriesNum), nodeParams);
|
||||||
|
cy.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function serviceMapAPICheck(body, entriesNum, nodeParams) {
|
||||||
|
const {nodes, edges} = body;
|
||||||
|
|
||||||
|
expect(nodes.length).to.equal(Object.keys(nodeParams).length, `Expected nodes count`);
|
||||||
|
|
||||||
|
expect(edges.some(edge => edge.source.name === nodeParams.source)).to.be.true;
|
||||||
|
expect(edges.some(edge => edge.destination.name === nodeParams.destination)).to.be.true;
|
||||||
|
|
||||||
|
let count = 0;
|
||||||
|
edges.forEach(edge => {
|
||||||
|
count += edge.count;
|
||||||
|
if (edge.destination.name === nodeParams.destination) {
|
||||||
|
expect(edge.source.name).to.equal(nodeParams.source);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(count).to.equal(entriesNum);
|
||||||
}
|
}
|
||||||
|
|||||||
240
acceptanceTests/extensions_test.go
Normal file
240
acceptanceTests/extensions_test.go
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
package acceptanceTests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-redis/redis/v8"
|
||||||
|
amqp "github.com/rabbitmq/amqp091-go"
|
||||||
|
"os/exec"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestRedis(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("ignored acceptance test")
|
||||||
|
}
|
||||||
|
|
||||||
|
cliPath, cliPathErr := GetCliPath()
|
||||||
|
if cliPathErr != nil {
|
||||||
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tapCmd.Start(); err != nil {
|
||||||
|
t.Errorf("failed to start tap command, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
kubernetesProvider, err := NewKubernetesProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create k8s provider, err %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
redisExternalIp, err := kubernetesProvider.GetServiceExternalIp(ctx, DefaultNamespaceName, "redis")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to get redis external ip, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rdb := redis.NewClient(&redis.Options{
|
||||||
|
Addr: fmt.Sprintf("%v:6379", redisExternalIp),
|
||||||
|
})
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
requestErr := rdb.Ping(ctx).Err()
|
||||||
|
if requestErr != nil {
|
||||||
|
t.Errorf("failed to send redis request, err: %v", requestErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
requestErr := rdb.Set(ctx, "key", "value", -1).Err()
|
||||||
|
if requestErr != nil {
|
||||||
|
t.Errorf("failed to send redis request, err: %v", requestErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
requestErr := rdb.Exists(ctx, "key").Err()
|
||||||
|
if requestErr != nil {
|
||||||
|
t.Errorf("failed to send redis request, err: %v", requestErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
requestErr := rdb.Get(ctx, "key").Err()
|
||||||
|
if requestErr != nil {
|
||||||
|
t.Errorf("failed to send redis request, err: %v", requestErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
requestErr := rdb.Del(ctx, "key").Err()
|
||||||
|
if requestErr != nil {
|
||||||
|
t.Errorf("failed to send redis request, err: %v", requestErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/Redis.js\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAmqp(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("ignored acceptance test")
|
||||||
|
}
|
||||||
|
|
||||||
|
cliPath, cliPathErr := GetCliPath()
|
||||||
|
if cliPathErr != nil {
|
||||||
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tapCmd.Start(); err != nil {
|
||||||
|
t.Errorf("failed to start tap command, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
kubernetesProvider, err := NewKubernetesProvider()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create k8s provider, err %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
rabbitmqExternalIp, err := kubernetesProvider.GetServiceExternalIp(ctx, DefaultNamespaceName, "rabbitmq")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to get RabbitMQ external ip, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := amqp.Dial(fmt.Sprintf("amqp://guest:guest@%v:5672/", rabbitmqExternalIp))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to connect to RabbitMQ, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
// Temporary fix for missing amqp entries
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
for i := 0; i < DefaultEntriesCount/5; i++ {
|
||||||
|
ch, err := conn.Channel()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to open a channel, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
exchangeName := "exchange"
|
||||||
|
err = ch.ExchangeDeclare(exchangeName, "direct", true, false, false, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to declare an exchange, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
q, err := ch.QueueDeclare("queue", true, false, false, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to declare a queue, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
routingKey := "routing_key"
|
||||||
|
err = ch.QueueBind(q.Name, routingKey, exchangeName, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to bind the queue, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ch.Publish(exchangeName, routingKey, false, false,
|
||||||
|
amqp.Publishing{
|
||||||
|
DeliveryMode: amqp.Persistent,
|
||||||
|
ContentType: "text/plain",
|
||||||
|
Body: []byte("message"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to publish a message, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msgChan, err := ch.Consume(q.Name, "Consumer", true, false, false, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to create a consumer, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-msgChan:
|
||||||
|
break
|
||||||
|
case <-time.After(3 * time.Second):
|
||||||
|
t.Errorf("failed to consume a message on time")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ch.ExchangeDelete(exchangeName, false, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to delete the exchange, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = ch.QueueDelete(q.Name, false, false, false)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to delete the queue, err: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ch.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/Rabbit.js\"")
|
||||||
|
}
|
||||||
@@ -1,11 +1,50 @@
|
|||||||
module github.com/up9inc/mizu/tests
|
module github.com/up9inc/mizu/acceptanceTests
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/go-redis/redis/v8 v8.11.4
|
||||||
|
github.com/rabbitmq/amqp091-go v1.3.0
|
||||||
github.com/up9inc/mizu/shared v0.0.0
|
github.com/up9inc/mizu/shared v0.0.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
|
k8s.io/apimachinery v0.23.3
|
||||||
|
k8s.io/client-go v0.23.3
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
github.com/go-logr/logr v1.2.2 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.7 // indirect
|
||||||
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
k8s.io/api v0.23.3 // indirect
|
||||||
|
k8s.io/klog/v2 v2.40.1 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
||||||
|
|||||||
@@ -9,26 +9,44 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
|
|||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
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.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.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 v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||||
|
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||||
|
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||||
|
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||||
|
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
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.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.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.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/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/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.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.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.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.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.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.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=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||||
|
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||||
|
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||||
|
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
@@ -57,13 +75,19 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
|
|||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
|
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||||
|
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
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/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/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
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-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
|
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
@@ -79,6 +103,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
@@ -87,17 +113,25 @@ github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3
|
|||||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/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 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/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.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.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
|
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||||
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
|
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
|
||||||
|
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
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/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||||
@@ -111,8 +145,10 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
|
|||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
|
||||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
|
||||||
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
|
||||||
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||||
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
|
||||||
@@ -125,6 +161,7 @@ github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwds
|
|||||||
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||||
@@ -154,29 +191,38 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
|||||||
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
|
||||||
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
|
||||||
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||||
|
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
|
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||||
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
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.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0=
|
|
||||||
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8eU=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/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-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-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/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
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.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.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.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.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/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||||
github.com/golang/protobuf v1.2.0/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.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.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.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.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/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.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.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
@@ -185,26 +231,46 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
|||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
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.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||||
|
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||||
|
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/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.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.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.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
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.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.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
|
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
|
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||||
|
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
|
||||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||||
|
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
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/martian/v3 v3.1.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-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-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-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-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-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/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
|
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
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/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.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@@ -213,9 +279,12 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
|||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
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/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
|
||||||
|
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||||
|
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
|
||||||
|
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
|
||||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
@@ -243,12 +312,16 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
|
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||||
|
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
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.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.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/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
@@ -296,21 +369,33 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
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.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/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||||
|
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||||
|
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||||
|
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
||||||
|
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.7.0/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/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||||
|
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||||
|
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||||
|
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
@@ -342,6 +427,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
|
|||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
github.com/rabbitmq/amqp091-go v1.3.0 h1:A/QuHiNw7LMCJsxx9iZn5lrIz6OrhIn7Dfk5/1YatWM=
|
||||||
|
github.com/rabbitmq/amqp091-go v1.3.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
|
||||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
@@ -369,14 +456,17 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||||
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
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.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
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.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/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
@@ -385,8 +475,11 @@ github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv
|
|||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
|
||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||||
|
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.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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||||
@@ -395,6 +488,9 @@ 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.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
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.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
|
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||||
|
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||||
go.uber.org/atomic v1.4.0/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/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
@@ -411,6 +507,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||||
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -433,6 +530,7 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
|
|||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
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-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-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||||
|
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/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-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/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.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
@@ -442,6 +540,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
|
|||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -461,6 +562,7 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
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-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-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-20190724013045-ca1201d0de80/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-20190827160401-ba9fcec4b297/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-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
@@ -470,22 +572,52 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/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-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-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
|
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-20200520004742-59133d7f0dd7/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM=
|
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
|
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||||
|
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-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-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-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-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/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-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-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-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-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-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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -504,10 +636,12 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/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-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-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/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-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@@ -518,26 +652,58 @@ golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/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-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-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-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/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-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/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-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d/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-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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.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.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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4 h1:0YWbFKbhXG/wIiuHDSKpS0Iy7FSA+u45VtBMfQcFTTc=
|
|
||||||
golang.org/x/text v0.3.4/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-20181108054448-85acf8d2951c/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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 h1:GZokNIeuVkl3aZHJchRrr13WCsols02MLUcz1U9is6M=
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/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-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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@@ -574,11 +740,28 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
|
|||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/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-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-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-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-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/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-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/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-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||||
|
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
|
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -593,12 +776,26 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
|
|||||||
google.golang.org/api v0.15.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.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.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.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/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||||
|
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||||
|
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||||
|
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||||
|
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.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.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.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
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-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-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
@@ -616,16 +813,48 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx
|
|||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
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-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-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-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-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-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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
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.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
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.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
|
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.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.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.27.1/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.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||||
|
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||||
|
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||||
|
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
|
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
|
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
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-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
@@ -634,7 +863,12 @@ 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.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.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.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
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.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 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||||
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
@@ -647,6 +881,7 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
|||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@@ -655,9 +890,11 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
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.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||||
@@ -668,34 +905,54 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/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-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.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
|
k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
|
||||||
k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc=
|
k8s.io/api v0.23.3 h1:KNrME8KHGr12Ozjf8ytOewKzZh6hl/hHUZeHddT3a38=
|
||||||
|
k8s.io/api v0.23.3/go.mod h1:w258XdGyvCmnBj/vGzQMj6kzdufJZVUwEM1U2fRJwSQ=
|
||||||
k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
|
k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
|
||||||
|
k8s.io/apimachinery v0.23.3 h1:7IW6jxNzrXTsP0c8yXz2E5Yx/WTzVPTsHIx/2Vm0cIk=
|
||||||
|
k8s.io/apimachinery v0.23.3/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
|
||||||
k8s.io/cli-runtime v0.21.2/go.mod h1:8u/jFcM0QpoI28f6sfrAAIslLCXUYKD5SsPPMWiHYrI=
|
k8s.io/cli-runtime v0.21.2/go.mod h1:8u/jFcM0QpoI28f6sfrAAIslLCXUYKD5SsPPMWiHYrI=
|
||||||
k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA=
|
k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA=
|
||||||
|
k8s.io/client-go v0.23.3 h1:23QYUmCQ/W6hW78xIwm3XqZrrKZM+LWDqW2zfo+szJs=
|
||||||
|
k8s.io/client-go v0.23.3/go.mod h1:47oMd+YvAOqZM7pcQ6neJtBiFH7alOyfunYN48VsmwE=
|
||||||
k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U=
|
k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U=
|
||||||
k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc=
|
k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc=
|
||||||
k8s.io/component-helpers v0.21.2/go.mod h1:DbyFt/A0p6Cv+R5+QOGSJ5f5t4xDfI8Yb89a57DgJlQ=
|
k8s.io/component-helpers v0.21.2/go.mod h1:DbyFt/A0p6Cv+R5+QOGSJ5f5t4xDfI8Yb89a57DgJlQ=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
|
||||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||||
|
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
|
k8s.io/klog/v2 v2.40.1 h1:P4RRucWk/lFOlDdkAr3mc7iWFkgKrZY9qZMAgek06S4=
|
||||||
|
k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf h1:M9XBsiMslw2lb2ZzglC0TOkBPK5NQi0/noUrdnoFwUg=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||||
k8s.io/kubectl v0.21.2/go.mod h1:PgeUclpG8VVmmQIl8zpLar3IQEpFc9mrmvlwY3CK1xo=
|
k8s.io/kubectl v0.21.2/go.mod h1:PgeUclpG8VVmmQIl8zpLar3IQEpFc9mrmvlwY3CK1xo=
|
||||||
k8s.io/metrics v0.21.2/go.mod h1:wzlOINZMCtWq8dR9gHlyaOemmYlOpAoldEIXE82gAhI=
|
k8s.io/metrics v0.21.2/go.mod h1:wzlOINZMCtWq8dR9gHlyaOemmYlOpAoldEIXE82gAhI=
|
||||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
|
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
|
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65 h1:ONWS0Wgdg5wRiQIAui7L/023aC9+IxrIrydY7l8llsE=
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
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/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
|
sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs=
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 h1:kDi4JBNAsJWfz1aEXhO8Jg87JJaPNLh5tIzYHgStQ9Y=
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY=
|
||||||
sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY=
|
sigs.k8s.io/kustomize/api v0.8.8/go.mod h1:He1zoK0nk43Pc6NlV085xDXDXTNprtcyKZVm3swsdNY=
|
||||||
sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0=
|
sigs.k8s.io/kustomize/cmd/config v0.9.10/go.mod h1:Mrby0WnRH7hA6OwOYnYpfpiY0WJIMgYrEDfwOeFdMK0=
|
||||||
sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo=
|
sigs.k8s.io/kustomize/kustomize/v4 v4.1.2/go.mod h1:PxBvo4WGYlCLeRPL+ziT64wBXqbgfcalOS/SXa/tcyo=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg=
|
sigs.k8s.io/kustomize/kyaml v0.10.17/go.mod h1:mlQFagmkm1P+W4lZJbJ/yaxMd8PqMRSC4cPcfUVt5Hg=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||||
|
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||||
|
|||||||
@@ -11,22 +11,22 @@ func TestLogs(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -36,14 +36,14 @@ func TestLogs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logsCmdArgs := getDefaultLogsCommandArgs()
|
logsCmdArgs := GetDefaultLogsCommandArgs()
|
||||||
|
|
||||||
logsCmd := exec.Command(cliPath, logsCmdArgs...)
|
logsCmd := exec.Command(cliPath, logsCmdArgs...)
|
||||||
t.Logf("running command: %v", logsCmd.String())
|
t.Logf("running command: %v", logsCmd.String())
|
||||||
@@ -58,7 +58,7 @@ func TestLogs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logsPath, logsPathErr := getLogsPath()
|
logsPath, logsPathErr := GetLogsPath()
|
||||||
if logsPathErr != nil {
|
if logsPathErr != nil {
|
||||||
t.Errorf("failed to get logs path, err: %v", logsPathErr)
|
t.Errorf("failed to get logs path, err: %v", logsPathErr)
|
||||||
return
|
return
|
||||||
@@ -112,22 +112,22 @@ func TestLogsPath(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -137,14 +137,14 @@ func TestLogsPath(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
logsCmdArgs := getDefaultLogsCommandArgs()
|
logsCmdArgs := GetDefaultLogsCommandArgs()
|
||||||
|
|
||||||
logsPath := "../logs.zip"
|
logsPath := "../logs.zip"
|
||||||
logsCmdArgs = append(logsCmdArgs, "-f", logsPath)
|
logsCmdArgs = append(logsCmdArgs, "-f", logsPath)
|
||||||
|
|||||||
@@ -36,12 +36,24 @@ kubectl create deployment httpbin2 --image=kennethreitz/httpbin -n mizu-tests
|
|||||||
|
|
||||||
kubectl create deployment httpbin --image=kennethreitz/httpbin -n mizu-tests2
|
kubectl create deployment httpbin --image=kennethreitz/httpbin -n mizu-tests2
|
||||||
|
|
||||||
|
echo "Creating redis deployment"
|
||||||
|
kubectl create deployment redis --image=redis -n mizu-tests
|
||||||
|
|
||||||
|
echo "Creating rabbitmq deployment"
|
||||||
|
kubectl create deployment rabbitmq --image=rabbitmq -n mizu-tests
|
||||||
|
|
||||||
echo "Creating httpbin services"
|
echo "Creating httpbin services"
|
||||||
kubectl expose deployment httpbin --type=NodePort --port=80 -n mizu-tests
|
kubectl expose deployment httpbin --type=NodePort --port=80 -n mizu-tests
|
||||||
kubectl expose deployment httpbin2 --type=NodePort --port=80 -n mizu-tests
|
kubectl expose deployment httpbin2 --type=NodePort --port=80 -n mizu-tests
|
||||||
|
|
||||||
kubectl expose deployment httpbin --type=NodePort --port=80 -n mizu-tests2
|
kubectl expose deployment httpbin --type=NodePort --port=80 -n mizu-tests2
|
||||||
|
|
||||||
|
echo "Creating redis service"
|
||||||
|
kubectl expose deployment redis --type=LoadBalancer --port=6379 -n mizu-tests
|
||||||
|
|
||||||
|
echo "Creating rabbitmq service"
|
||||||
|
kubectl expose deployment rabbitmq --type=LoadBalancer --port=5672 -n mizu-tests
|
||||||
|
|
||||||
echo "Starting proxy"
|
echo "Starting proxy"
|
||||||
kubectl proxy --port=8080 &
|
kubectl proxy --port=8080 &
|
||||||
|
|
||||||
@@ -53,3 +65,6 @@ make build-docker-ci
|
|||||||
|
|
||||||
echo "Build cli"
|
echo "Build cli"
|
||||||
make build-cli-ci
|
make build-cli-ci
|
||||||
|
|
||||||
|
echo "Starting tunnel"
|
||||||
|
minikube tunnel &
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestTap(t *testing.T) {
|
func TestTap(t *testing.T) {
|
||||||
|
basicTapTest(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func basicTapTest(t *testing.T, shouldCheckSrcAndDest bool, extraArgs... string) {
|
||||||
if testing.Short() {
|
if testing.Short() {
|
||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
@@ -22,22 +26,24 @@ func TestTap(t *testing.T) {
|
|||||||
|
|
||||||
for _, entriesCount := range tests {
|
for _, entriesCount := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", entriesCount), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", entriesCount), func(t *testing.T) {
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
|
tapCmdArgs = append(tapCmdArgs, extraArgs...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -47,22 +53,33 @@ func TestTap(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
for i := 0; i < entriesCount; i++ {
|
for i := 0; i < entriesCount; i++ {
|
||||||
if _, requestErr := executeHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
if _, requestErr := ExecuteHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/UiTest.js\"")
|
expectedPods := []PodDescriptor{
|
||||||
|
{Name: "httpbin", Namespace: "mizu-tests"},
|
||||||
|
{Name: "httpbin2", Namespace: "mizu-tests"},
|
||||||
|
}
|
||||||
|
|
||||||
|
var expectedPodsStr string
|
||||||
|
for i := 0; i < len(expectedPods); i++ {
|
||||||
|
expectedPodsStr += fmt.Sprintf("Name:%vNamespace:%v", expectedPods[i].Name, expectedPods[i].Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/UiTest.js\" --env entriesCount=%d,arrayDict=%v,shouldCheckSrcAndDest=%v",
|
||||||
|
entriesCount, expectedPodsStr, shouldCheckSrcAndDest))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,15 +93,15 @@ func TestTapGuiPort(t *testing.T) {
|
|||||||
|
|
||||||
for _, guiPort := range tests {
|
for _, guiPort := range tests {
|
||||||
t.Run(fmt.Sprintf("%d", guiPort), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%d", guiPort), func(t *testing.T) {
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "-p", fmt.Sprintf("%d", guiPort))
|
tapCmdArgs = append(tapCmdArgs, "-p", fmt.Sprintf("%d", guiPort))
|
||||||
@@ -93,7 +110,7 @@ func TestTapGuiPort(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -103,22 +120,22 @@ func TestTapGuiPort(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(guiPort)
|
apiServerUrl := GetApiServerUrl(guiPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
if _, requestErr := executeHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
if _, requestErr := ExecuteHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/GuiPort.js\" --env name=%v,namespace=%v,port=%d",
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/GuiPort.js\" --env name=%v,namespace=%v,port=%d",
|
||||||
"httpbin", "mizu-tests", guiPort))
|
"httpbin", "mizu-tests", guiPort))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -135,20 +152,20 @@ func TestTapAllNamespaces(t *testing.T) {
|
|||||||
{Name: "httpbin", Namespace: "mizu-tests2"},
|
{Name: "httpbin", Namespace: "mizu-tests2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
tapCmdArgs = append(tapCmdArgs, "-A")
|
tapCmdArgs = append(tapCmdArgs, "-A")
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -158,14 +175,14 @@ func TestTapAllNamespaces(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/MultipleNamespaces.js\" --env name1=%v,name2=%v,name3=%v,namespace1=%v,namespace2=%v,namespace3=%v",
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/MultipleNamespaces.js\" --env name1=%v,name2=%v,name3=%v,namespace1=%v,namespace2=%v,namespace3=%v",
|
||||||
expectedPods[0].Name, expectedPods[1].Name, expectedPods[2].Name, expectedPods[0].Namespace, expectedPods[1].Namespace, expectedPods[2].Namespace))
|
expectedPods[0].Name, expectedPods[1].Name, expectedPods[2].Name, expectedPods[0].Namespace, expectedPods[1].Namespace, expectedPods[2].Namespace))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,13 +197,13 @@ func TestTapMultipleNamespaces(t *testing.T) {
|
|||||||
{Name: "httpbin", Namespace: "mizu-tests2"},
|
{Name: "httpbin", Namespace: "mizu-tests2"},
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
var namespacesCmd []string
|
var namespacesCmd []string
|
||||||
for _, expectedPod := range expectedPods {
|
for _, expectedPod := range expectedPods {
|
||||||
namespacesCmd = append(namespacesCmd, "-n", expectedPod.Namespace)
|
namespacesCmd = append(namespacesCmd, "-n", expectedPod.Namespace)
|
||||||
@@ -197,7 +214,7 @@ func TestTapMultipleNamespaces(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -207,14 +224,14 @@ func TestTapMultipleNamespaces(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/MultipleNamespaces.js\" --env name1=%v,name2=%v,name3=%v,namespace1=%v,namespace2=%v,namespace3=%v",
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/MultipleNamespaces.js\" --env name1=%v,name2=%v,name3=%v,namespace1=%v,namespace2=%v,namespace3=%v",
|
||||||
expectedPods[0].Name, expectedPods[1].Name, expectedPods[2].Name, expectedPods[0].Namespace, expectedPods[1].Namespace, expectedPods[2].Namespace))
|
expectedPods[0].Name, expectedPods[1].Name, expectedPods[2].Name, expectedPods[0].Namespace, expectedPods[1].Namespace, expectedPods[2].Namespace))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,22 +245,22 @@ func TestTapRegex(t *testing.T) {
|
|||||||
{Name: regexPodName, Namespace: "mizu-tests"},
|
{Name: regexPodName, Namespace: "mizu-tests"},
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgsWithRegex(regexPodName)
|
tapCmdArgs := GetDefaultTapCommandArgsWithRegex(regexPodName)
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -253,14 +270,14 @@ func TestTapRegex(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/Regex.js\" --env name=%v,namespace=%v",
|
RunCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/Regex.js\" --env name=%v,namespace=%v",
|
||||||
expectedPods[0].Name, expectedPods[0].Namespace))
|
expectedPods[0].Name, expectedPods[0].Namespace))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,15 +286,15 @@ func TestTapDryRun(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "--dry-run")
|
tapCmdArgs = append(tapCmdArgs, "--dry-run")
|
||||||
@@ -301,7 +318,7 @@ func TestTapDryRun(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
time.Sleep(shortRetriesCount * time.Second)
|
time.Sleep(ShortRetriesCount * time.Second)
|
||||||
resultChannel <- "fail"
|
resultChannel <- "fail"
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -316,22 +333,22 @@ func TestTapRedact(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
tapCmd := exec.Command(cliPath, tapCmdArgs...)
|
||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -341,24 +358,24 @@ func TestTapRedact(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
requestHeaders := map[string]string{"User-Header": "Mizu"}
|
requestHeaders := map[string]string{"User-Header": "Mizu"}
|
||||||
requestBody := map[string]string{"User": "Mizu"}
|
requestBody := map[string]string{"User": "Mizu"}
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
if _, requestErr := executeHttpPostRequestWithHeaders(fmt.Sprintf("%v/post", proxyUrl), requestHeaders, requestBody); requestErr != nil {
|
if _, requestErr := ExecuteHttpPostRequestWithHeaders(fmt.Sprintf("%v/post", proxyUrl), requestHeaders, requestBody); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/Redact.js\"")
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/Redact.js\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTapNoRedact(t *testing.T) {
|
func TestTapNoRedact(t *testing.T) {
|
||||||
@@ -366,15 +383,15 @@ func TestTapNoRedact(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "--no-redact")
|
tapCmdArgs = append(tapCmdArgs, "--no-redact")
|
||||||
@@ -383,7 +400,7 @@ func TestTapNoRedact(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -393,24 +410,24 @@ func TestTapNoRedact(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
requestHeaders := map[string]string{"User-Header": "Mizu"}
|
requestHeaders := map[string]string{"User-Header": "Mizu"}
|
||||||
requestBody := map[string]string{"User": "Mizu"}
|
requestBody := map[string]string{"User": "Mizu"}
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
if _, requestErr := executeHttpPostRequestWithHeaders(fmt.Sprintf("%v/post", proxyUrl), requestHeaders, requestBody); requestErr != nil {
|
if _, requestErr := ExecuteHttpPostRequestWithHeaders(fmt.Sprintf("%v/post", proxyUrl), requestHeaders, requestBody); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/NoRedact.js\"")
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/NoRedact.js\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTapRegexMasking(t *testing.T) {
|
func TestTapRegexMasking(t *testing.T) {
|
||||||
@@ -418,15 +435,15 @@ func TestTapRegexMasking(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "-r", "Mizu")
|
tapCmdArgs = append(tapCmdArgs, "-r", "Mizu")
|
||||||
@@ -435,7 +452,7 @@ func TestTapRegexMasking(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -445,23 +462,23 @@ func TestTapRegexMasking(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
response, requestErr := http.Post(fmt.Sprintf("%v/post", proxyUrl), "text/plain", bytes.NewBufferString("Mizu"))
|
response, requestErr := http.Post(fmt.Sprintf("%v/post", proxyUrl), "text/plain", bytes.NewBufferString("Mizu"))
|
||||||
if _, requestErr = executeHttpRequest(response, requestErr); requestErr != nil {
|
if _, requestErr = ExecuteHttpRequest(response, requestErr); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/RegexMasking.js\"")
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/RegexMasking.js\"")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,15 +487,15 @@ func TestTapIgnoredUserAgents(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
ignoredUserAgentValue := "ignore"
|
ignoredUserAgentValue := "ignore"
|
||||||
@@ -488,7 +505,7 @@ func TestTapIgnoredUserAgents(t *testing.T) {
|
|||||||
t.Logf("running command: %v", tapCmd.String())
|
t.Logf("running command: %v", tapCmd.String())
|
||||||
|
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Logf("failed to cleanup tap command, err: %v", err)
|
t.Logf("failed to cleanup tap command, err: %v", err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -498,32 +515,32 @@ func TestTapIgnoredUserAgents(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyUrl := getProxyUrl(defaultNamespaceName, defaultServiceName)
|
proxyUrl := GetProxyUrl(DefaultNamespaceName, DefaultServiceName)
|
||||||
|
|
||||||
ignoredUserAgentCustomHeader := "Ignored-User-Agent"
|
ignoredUserAgentCustomHeader := "Ignored-User-Agent"
|
||||||
headers := map[string]string{"User-Agent": ignoredUserAgentValue, ignoredUserAgentCustomHeader: ""}
|
headers := map[string]string{"User-Agent": ignoredUserAgentValue, ignoredUserAgentCustomHeader: ""}
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
if _, requestErr := executeHttpGetRequestWithHeaders(fmt.Sprintf("%v/get", proxyUrl), headers); requestErr != nil {
|
if _, requestErr := ExecuteHttpGetRequestWithHeaders(fmt.Sprintf("%v/get", proxyUrl), headers); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < defaultEntriesCount; i++ {
|
for i := 0; i < DefaultEntriesCount; i++ {
|
||||||
if _, requestErr := executeHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
if _, requestErr := ExecuteHttpGetRequest(fmt.Sprintf("%v/get", proxyUrl)); requestErr != nil {
|
||||||
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
t.Errorf("failed to send proxy request, err: %v", requestErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/IgnoredUserAgents.js\"")
|
RunCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/IgnoredUserAgents.js\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTapDumpLogs(t *testing.T) {
|
func TestTapDumpLogs(t *testing.T) {
|
||||||
@@ -531,15 +548,15 @@ func TestTapDumpLogs(t *testing.T) {
|
|||||||
t.Skip("ignored acceptance test")
|
t.Skip("ignored acceptance test")
|
||||||
}
|
}
|
||||||
|
|
||||||
cliPath, cliPathErr := getCliPath()
|
cliPath, cliPathErr := GetCliPath()
|
||||||
if cliPathErr != nil {
|
if cliPathErr != nil {
|
||||||
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
t.Errorf("failed to get cli path, err: %v", cliPathErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
tapCmdArgs := getDefaultTapCommandArgs()
|
tapCmdArgs := GetDefaultTapCommandArgs()
|
||||||
|
|
||||||
tapNamespace := getDefaultTapNamespace()
|
tapNamespace := GetDefaultTapNamespace()
|
||||||
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
tapCmdArgs = append(tapCmdArgs, tapNamespace...)
|
||||||
|
|
||||||
tapCmdArgs = append(tapCmdArgs, "--set", "dump-logs=true")
|
tapCmdArgs = append(tapCmdArgs, "--set", "dump-logs=true")
|
||||||
@@ -552,19 +569,19 @@ func TestTapDumpLogs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerUrl := getApiServerUrl(defaultApiServerPort)
|
apiServerUrl := GetApiServerUrl(DefaultApiServerPort)
|
||||||
|
|
||||||
if err := waitTapPodsReady(apiServerUrl); err != nil {
|
if err := WaitTapPodsReady(apiServerUrl); err != nil {
|
||||||
t.Errorf("failed to start tap pods on time, err: %v", err)
|
t.Errorf("failed to start tap pods on time, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cleanupCommand(tapCmd); err != nil {
|
if err := CleanupCommand(tapCmd); err != nil {
|
||||||
t.Errorf("failed to cleanup tap command, err: %v", err)
|
t.Errorf("failed to cleanup tap command, err: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mizuFolderPath, mizuPathErr := getMizuFolderPath()
|
mizuFolderPath, mizuPathErr := GetMizuFolderPath()
|
||||||
if mizuPathErr != nil {
|
if mizuPathErr != nil {
|
||||||
t.Errorf("failed to get mizu folder path, err: %v", mizuPathErr)
|
t.Errorf("failed to get mizu folder path, err: %v", mizuPathErr)
|
||||||
return
|
return
|
||||||
@@ -632,3 +649,44 @@ func TestTapDumpLogs(t *testing.T) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIpResolving(t *testing.T) {
|
||||||
|
namespace := AllNamespaces
|
||||||
|
|
||||||
|
t.Log("add permissions for ip-resolution for current user")
|
||||||
|
if err := ApplyKubeFilesForTest(
|
||||||
|
t,
|
||||||
|
"minikube",
|
||||||
|
namespace,
|
||||||
|
"../cli/cmd/permissionFiles/permissions-all-namespaces-ip-resolution-optional.yaml",
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to create k8s permissions, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
basicTapTest(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRestrictedMode(t *testing.T) {
|
||||||
|
namespace := "mizu-tests"
|
||||||
|
|
||||||
|
t.Log("creating permissions for restricted user")
|
||||||
|
if err := ApplyKubeFilesForTest(
|
||||||
|
t,
|
||||||
|
"minikube",
|
||||||
|
namespace,
|
||||||
|
"../cli/cmd/permissionFiles/permissions-ns-tap.yaml",
|
||||||
|
); err != nil {
|
||||||
|
t.Errorf("failed to create k8s permissions, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Log("switching k8s context to user")
|
||||||
|
if err := SwitchKubeContextForTest(t, "user-with-restricted-access"); err != nil {
|
||||||
|
t.Errorf("failed to switch k8s context, %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
extraArgs := []string{"--set", fmt.Sprintf("mizu-resources-namespace=%s", namespace)}
|
||||||
|
t.Run("basic tap", func (testingT *testing.T) {basicTapTest(testingT, false, extraArgs...)})
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,13 +2,19 @@ package acceptanceTests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/client-go/kubernetes"
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
"k8s.io/client-go/util/homedir"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -18,13 +24,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
longRetriesCount = 100
|
LongRetriesCount = 100
|
||||||
shortRetriesCount = 10
|
ShortRetriesCount = 10
|
||||||
defaultApiServerPort = shared.DefaultApiServerPort
|
DefaultApiServerPort = shared.DefaultApiServerPort
|
||||||
defaultNamespaceName = "mizu-tests"
|
DefaultNamespaceName = "mizu-tests"
|
||||||
defaultServiceName = "httpbin"
|
DefaultServiceName = "httpbin"
|
||||||
defaultEntriesCount = 50
|
DefaultEntriesCount = 50
|
||||||
waitAfterTapPodsReady = 3 * time.Second
|
WaitAfterTapPodsReady = 3 * time.Second
|
||||||
|
AllNamespaces = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
type PodDescriptor struct {
|
type PodDescriptor struct {
|
||||||
@@ -32,7 +39,7 @@ type PodDescriptor struct {
|
|||||||
Namespace string
|
Namespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCliPath() (string, error) {
|
func GetCliPath() (string, error) {
|
||||||
dir, filePathErr := os.Getwd()
|
dir, filePathErr := os.Getwd()
|
||||||
if filePathErr != nil {
|
if filePathErr != nil {
|
||||||
return "", filePathErr
|
return "", filePathErr
|
||||||
@@ -42,7 +49,7 @@ func getCliPath() (string, error) {
|
|||||||
return cliPath, nil
|
return cliPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMizuFolderPath() (string, error) {
|
func GetMizuFolderPath() (string, error) {
|
||||||
home, homeDirErr := os.UserHomeDir()
|
home, homeDirErr := os.UserHomeDir()
|
||||||
if homeDirErr != nil {
|
if homeDirErr != nil {
|
||||||
return "", homeDirErr
|
return "", homeDirErr
|
||||||
@@ -51,8 +58,8 @@ func getMizuFolderPath() (string, error) {
|
|||||||
return path.Join(home, ".mizu"), nil
|
return path.Join(home, ".mizu"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getConfigPath() (string, error) {
|
func GetConfigPath() (string, error) {
|
||||||
mizuFolderPath, mizuPathError := getMizuFolderPath()
|
mizuFolderPath, mizuPathError := GetMizuFolderPath()
|
||||||
if mizuPathError != nil {
|
if mizuPathError != nil {
|
||||||
return "", mizuPathError
|
return "", mizuPathError
|
||||||
}
|
}
|
||||||
@@ -60,72 +67,209 @@ func getConfigPath() (string, error) {
|
|||||||
return path.Join(mizuFolderPath, "config.yaml"), nil
|
return path.Join(mizuFolderPath, "config.yaml"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProxyUrl(namespace string, service string) string {
|
func GetProxyUrl(namespace string, service string) string {
|
||||||
return fmt.Sprintf("http://localhost:8080/api/v1/namespaces/%v/services/%v/proxy", namespace, service)
|
return fmt.Sprintf("http://localhost:8080/api/v1/namespaces/%v/services/%v/proxy", namespace, service)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getApiServerUrl(port uint16) string {
|
func GetApiServerUrl(port uint16) string {
|
||||||
return fmt.Sprintf("http://localhost:%v", port)
|
return fmt.Sprintf("http://localhost:%v", port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewKubernetesProvider() (*KubernetesProvider, error) {
|
||||||
|
home := homedir.HomeDir()
|
||||||
|
configLoadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: filepath.Join(home, ".kube", "config")}
|
||||||
|
clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||||
|
configLoadingRules,
|
||||||
|
&clientcmd.ConfigOverrides{
|
||||||
|
CurrentContext: "",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
restClientConfig, err := clientConfig.ClientConfig()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
clientSet, err := kubernetes.NewForConfig(restClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &KubernetesProvider{clientSet}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type KubernetesProvider struct {
|
||||||
|
clientSet *kubernetes.Clientset
|
||||||
|
}
|
||||||
|
|
||||||
|
func (kp *KubernetesProvider) GetServiceExternalIp(ctx context.Context, namespace string, service string) (string, error) {
|
||||||
|
serviceObj, err := kp.clientSet.CoreV1().Services(namespace).Get(ctx, service, metav1.GetOptions{})
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
externalIp := serviceObj.Status.LoadBalancer.Ingress[0].IP
|
||||||
|
return externalIp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SwitchKubeContextForTest(t *testing.T, newContextName string) error {
|
||||||
|
prevKubeContextName, err := GetKubeCurrentContextName()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := SetKubeCurrentContext(newContextName); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := SetKubeCurrentContext(prevKubeContextName); err != nil {
|
||||||
|
t.Errorf("failed to set Kubernetes context to %s, err: %v", prevKubeContextName, err)
|
||||||
|
t.Errorf("cleanup failed, subsequent tests may be affected")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetKubeCurrentContextName() (string, error) {
|
||||||
|
cmd := exec.Command("kubectl", "config", "current-context")
|
||||||
|
|
||||||
|
output, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(bytes.TrimSpace(output)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetKubeCurrentContext(contextName string) error {
|
||||||
|
cmd := exec.Command("kubectl", "config", "use-context", contextName)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyKubeFilesForTest(t *testing.T, kubeContext string, namespace string, filename ...string) error {
|
||||||
|
for i := range filename {
|
||||||
|
fname := filename[i]
|
||||||
|
if err := ApplyKubeFile(kubeContext, namespace, fname); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := DeleteKubeFile(kubeContext, namespace, fname); err != nil {
|
||||||
|
t.Errorf(
|
||||||
|
"failed to delete Kubernetes resources in namespace %s from filename %s, err: %v",
|
||||||
|
namespace,
|
||||||
|
fname,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplyKubeFile(kubeContext string, namespace string, filename string) (error) {
|
||||||
|
cmdArgs := []string{
|
||||||
|
"apply",
|
||||||
|
"--context", kubeContext,
|
||||||
|
"-f", filename,
|
||||||
|
}
|
||||||
|
if namespace != AllNamespaces {
|
||||||
|
cmdArgs = append(cmdArgs, "-n", namespace)
|
||||||
|
}
|
||||||
|
cmd := exec.Command("kubectl", cmdArgs...)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteKubeFile(kubeContext string, namespace string, filename string) error {
|
||||||
|
cmdArgs := []string{
|
||||||
|
"delete",
|
||||||
|
"--context", kubeContext,
|
||||||
|
"-f", filename,
|
||||||
|
}
|
||||||
|
if namespace != AllNamespaces {
|
||||||
|
cmdArgs = append(cmdArgs, "-n", namespace)
|
||||||
|
}
|
||||||
|
cmd := exec.Command("kubectl", cmdArgs...)
|
||||||
|
|
||||||
|
if output, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
return fmt.Errorf("%v, %s", err, string(output))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func getDefaultCommandArgs() []string {
|
func getDefaultCommandArgs() []string {
|
||||||
setFlag := "--set"
|
setFlag := "--set"
|
||||||
telemetry := "telemetry=false"
|
telemetry := "telemetry=false"
|
||||||
agentImage := "agent-image=gcr.io/up9-docker-hub/mizu/ci:0.0.0"
|
agentImage := "agent-image=gcr.io/up9-docker-hub/mizu/ci:0.0"
|
||||||
imagePullPolicy := "image-pull-policy=IfNotPresent"
|
imagePullPolicy := "image-pull-policy=IfNotPresent"
|
||||||
headless := "headless=true"
|
headless := "headless=true"
|
||||||
|
|
||||||
return []string{setFlag, telemetry, setFlag, agentImage, setFlag, imagePullPolicy, setFlag, headless}
|
return []string{setFlag, telemetry, setFlag, agentImage, setFlag, imagePullPolicy, setFlag, headless}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultTapCommandArgs() []string {
|
func GetDefaultTapCommandArgs() []string {
|
||||||
tapCommand := "tap"
|
tapCommand := "tap"
|
||||||
defaultCmdArgs := getDefaultCommandArgs()
|
defaultCmdArgs := getDefaultCommandArgs()
|
||||||
|
|
||||||
return append([]string{tapCommand}, defaultCmdArgs...)
|
return append([]string{tapCommand}, defaultCmdArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultTapCommandArgsWithRegex(regex string) []string {
|
func GetDefaultTapCommandArgsWithRegex(regex string) []string {
|
||||||
tapCommand := "tap"
|
tapCommand := "tap"
|
||||||
defaultCmdArgs := getDefaultCommandArgs()
|
defaultCmdArgs := getDefaultCommandArgs()
|
||||||
|
|
||||||
return append([]string{tapCommand, regex}, defaultCmdArgs...)
|
return append([]string{tapCommand, regex}, defaultCmdArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultLogsCommandArgs() []string {
|
func GetDefaultLogsCommandArgs() []string {
|
||||||
logsCommand := "logs"
|
logsCommand := "logs"
|
||||||
defaultCmdArgs := getDefaultCommandArgs()
|
defaultCmdArgs := getDefaultCommandArgs()
|
||||||
|
|
||||||
return append([]string{logsCommand}, defaultCmdArgs...)
|
return append([]string{logsCommand}, defaultCmdArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultTapNamespace() []string {
|
func GetDefaultTapNamespace() []string {
|
||||||
return []string{"-n", "mizu-tests"}
|
return []string{"-n", "mizu-tests"}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultConfigCommandArgs() []string {
|
func GetDefaultConfigCommandArgs() []string {
|
||||||
configCommand := "config"
|
configCommand := "config"
|
||||||
defaultCmdArgs := getDefaultCommandArgs()
|
defaultCmdArgs := getDefaultCommandArgs()
|
||||||
|
|
||||||
return append([]string{configCommand}, defaultCmdArgs...)
|
return append([]string{configCommand}, defaultCmdArgs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runCypressTests(t *testing.T, cypressRunCmd string) {
|
func RunCypressTests(t *testing.T, cypressRunCmd string) {
|
||||||
cypressCmd := exec.Command("bash", "-c", cypressRunCmd)
|
cypressCmd := exec.Command("bash", "-c", cypressRunCmd)
|
||||||
t.Logf("running command: %v", cypressCmd.String())
|
t.Logf("running command: %v", cypressCmd.String())
|
||||||
out, err := cypressCmd.Output()
|
out, err := cypressCmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s", out)
|
t.Errorf("error running cypress, error: %v, output: %v", err, string(out))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("%s", out)
|
t.Logf("%s", out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func retriesExecute(retriesCount int, executeFunc func() error) error {
|
func RetriesExecute(retriesCount int, executeFunc func() error) error {
|
||||||
var lastError interface{}
|
var lastError interface{}
|
||||||
|
|
||||||
for i := 0; i < retriesCount; i++ {
|
for i := 0; i < retriesCount; i++ {
|
||||||
if err := tryExecuteFunc(executeFunc); err != nil {
|
if err := TryExecuteFunc(executeFunc); err != nil {
|
||||||
lastError = err
|
lastError = err
|
||||||
|
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
@@ -138,7 +282,7 @@ func retriesExecute(retriesCount int, executeFunc func() error) error {
|
|||||||
return fmt.Errorf("reached max retries count, retries count: %v, last err: %v", retriesCount, lastError)
|
return fmt.Errorf("reached max retries count, retries count: %v, last err: %v", retriesCount, lastError)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tryExecuteFunc(executeFunc func() error) (err interface{}) {
|
func TryExecuteFunc(executeFunc func() error) (err interface{}) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if panicErr := recover(); panicErr != nil {
|
if panicErr := recover(); panicErr != nil {
|
||||||
err = panicErr
|
err = panicErr
|
||||||
@@ -148,10 +292,10 @@ func tryExecuteFunc(executeFunc func() error) (err interface{}) {
|
|||||||
return executeFunc()
|
return executeFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitTapPodsReady(apiServerUrl string) error {
|
func WaitTapPodsReady(apiServerUrl string) error {
|
||||||
resolvingUrl := fmt.Sprintf("%v/status/connectedTappersCount", apiServerUrl)
|
resolvingUrl := fmt.Sprintf("%v/status/connectedTappersCount", apiServerUrl)
|
||||||
tapPodsReadyFunc := func() error {
|
tapPodsReadyFunc := func() error {
|
||||||
requestResult, requestErr := executeHttpGetRequest(resolvingUrl)
|
requestResult, requestErr := ExecuteHttpGetRequest(resolvingUrl)
|
||||||
if requestErr != nil {
|
if requestErr != nil {
|
||||||
return requestErr
|
return requestErr
|
||||||
}
|
}
|
||||||
@@ -160,14 +304,14 @@ func waitTapPodsReady(apiServerUrl string) error {
|
|||||||
if connectedTappersCount == 0 {
|
if connectedTappersCount == 0 {
|
||||||
return fmt.Errorf("no connected tappers running")
|
return fmt.Errorf("no connected tappers running")
|
||||||
}
|
}
|
||||||
time.Sleep(waitAfterTapPodsReady)
|
time.Sleep(WaitAfterTapPodsReady)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return retriesExecute(longRetriesCount, tapPodsReadyFunc)
|
return RetriesExecute(LongRetriesCount, tapPodsReadyFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonBytesToInterface(jsonBytes []byte) (interface{}, error) {
|
func JsonBytesToInterface(jsonBytes []byte) (interface{}, error) {
|
||||||
var result interface{}
|
var result interface{}
|
||||||
if parseErr := json.Unmarshal(jsonBytes, &result); parseErr != nil {
|
if parseErr := json.Unmarshal(jsonBytes, &result); parseErr != nil {
|
||||||
return nil, parseErr
|
return nil, parseErr
|
||||||
@@ -176,7 +320,7 @@ func jsonBytesToInterface(jsonBytes []byte) (interface{}, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeHttpRequest(response *http.Response, requestErr error) (interface{}, error) {
|
func ExecuteHttpRequest(response *http.Response, requestErr error) (interface{}, error) {
|
||||||
if requestErr != nil {
|
if requestErr != nil {
|
||||||
return nil, requestErr
|
return nil, requestErr
|
||||||
} else if response.StatusCode != 200 {
|
} else if response.StatusCode != 200 {
|
||||||
@@ -190,10 +334,10 @@ func executeHttpRequest(response *http.Response, requestErr error) (interface{},
|
|||||||
return nil, readErr
|
return nil, readErr
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonBytesToInterface(data)
|
return JsonBytesToInterface(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeHttpGetRequestWithHeaders(url string, headers map[string]string) (interface{}, error) {
|
func ExecuteHttpGetRequestWithHeaders(url string, headers map[string]string) (interface{}, error) {
|
||||||
request, err := http.NewRequest(http.MethodGet, url, nil)
|
request, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -205,15 +349,15 @@ func executeHttpGetRequestWithHeaders(url string, headers map[string]string) (in
|
|||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
response, requestErr := client.Do(request)
|
response, requestErr := client.Do(request)
|
||||||
return executeHttpRequest(response, requestErr)
|
return ExecuteHttpRequest(response, requestErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeHttpGetRequest(url string) (interface{}, error) {
|
func ExecuteHttpGetRequest(url string) (interface{}, error) {
|
||||||
response, requestErr := http.Get(url)
|
response, requestErr := http.Get(url)
|
||||||
return executeHttpRequest(response, requestErr)
|
return ExecuteHttpRequest(response, requestErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func executeHttpPostRequestWithHeaders(url string, headers map[string]string, body interface{}) (interface{}, error) {
|
func ExecuteHttpPostRequestWithHeaders(url string, headers map[string]string, body interface{}) (interface{}, error) {
|
||||||
requestBody, jsonErr := json.Marshal(body)
|
requestBody, jsonErr := json.Marshal(body)
|
||||||
if jsonErr != nil {
|
if jsonErr != nil {
|
||||||
return nil, jsonErr
|
return nil, jsonErr
|
||||||
@@ -231,10 +375,10 @@ func executeHttpPostRequestWithHeaders(url string, headers map[string]string, bo
|
|||||||
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
response, requestErr := client.Do(request)
|
response, requestErr := client.Do(request)
|
||||||
return executeHttpRequest(response, requestErr)
|
return ExecuteHttpRequest(response, requestErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanupCommand(cmd *exec.Cmd) error {
|
func CleanupCommand(cmd *exec.Cmd) error {
|
||||||
if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
|
if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -246,7 +390,7 @@ func cleanupCommand(cmd *exec.Cmd) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLogsPath() (string, error) {
|
func GetLogsPath() (string, error) {
|
||||||
dir, filePathErr := os.Getwd()
|
dir, filePathErr := os.Getwd()
|
||||||
if filePathErr != nil {
|
if filePathErr != nil {
|
||||||
return "", filePathErr
|
return "", filePathErr
|
||||||
|
|||||||
141
agent/go.mod
141
agent/go.mod
@@ -1,28 +1,28 @@
|
|||||||
module github.com/up9inc/mizu/agent
|
module github.com/up9inc/mizu/agent
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/antelman107/net-wait-go v0.0.0-20210623112055-cf684aebda7b
|
github.com/antelman107/net-wait-go v0.0.0-20210623112055-cf684aebda7b
|
||||||
github.com/chanced/openapi v0.0.7
|
github.com/chanced/openapi v0.0.8
|
||||||
github.com/djherbis/atime v1.0.0
|
github.com/djherbis/atime v1.1.0
|
||||||
github.com/elastic/go-elasticsearch/v7 v7.16.0
|
github.com/elastic/go-elasticsearch/v7 v7.17.0
|
||||||
github.com/getkin/kin-openapi v0.76.0
|
github.com/getkin/kin-openapi v0.89.0
|
||||||
github.com/gin-contrib/static v0.0.1
|
github.com/gin-contrib/static v0.0.1
|
||||||
github.com/gin-gonic/gin v1.7.7
|
github.com/gin-gonic/gin v1.7.7
|
||||||
github.com/go-playground/locales v0.13.0
|
github.com/go-playground/locales v0.14.0
|
||||||
github.com/go-playground/universal-translator v0.17.0
|
github.com/go-playground/universal-translator v0.18.0
|
||||||
github.com/go-playground/validator/v10 v10.5.0
|
github.com/go-playground/validator/v10 v10.10.0
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.3.0
|
||||||
github.com/gorilla/websocket v1.4.2
|
github.com/gorilla/websocket v1.4.2
|
||||||
github.com/nav-inc/datetime v0.1.3
|
github.com/nav-inc/datetime v0.1.3
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231
|
github.com/orcaman/concurrent-map v1.0.0
|
||||||
github.com/ory/keto-client-go v0.7.0-alpha.1
|
github.com/ory/keto-client-go v0.7.0-alpha.1
|
||||||
github.com/ory/kratos-client-go v0.8.2-alpha.1
|
github.com/ory/kratos-client-go v0.8.2-alpha.1
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/up9inc/basenine/client/go v0.0.0-20220125035724-573fff0d5075
|
github.com/up9inc/basenine/client/go v0.0.0-20220302073458-c32e0adf1500
|
||||||
github.com/up9inc/mizu/shared v0.0.0
|
github.com/up9inc/mizu/shared v0.0.0
|
||||||
github.com/up9inc/mizu/tap v0.0.0
|
github.com/up9inc/mizu/tap v0.0.0
|
||||||
github.com/up9inc/mizu/tap/api v0.0.0
|
github.com/up9inc/mizu/tap/api v0.0.0
|
||||||
@@ -32,9 +32,122 @@ require (
|
|||||||
github.com/up9inc/mizu/tap/extensions/redis v0.0.0
|
github.com/up9inc/mizu/tap/extensions/redis v0.0.0
|
||||||
github.com/wI2L/jsondiff v0.1.1
|
github.com/wI2L/jsondiff v0.1.1
|
||||||
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0
|
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0
|
||||||
k8s.io/api v0.21.2
|
k8s.io/api v0.23.3
|
||||||
k8s.io/apimachinery v0.21.2
|
k8s.io/apimachinery v0.23.3
|
||||||
k8s.io/client-go v0.21.2
|
k8s.io/client-go v0.23.3
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go/compute v1.2.0 // indirect
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
|
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest v0.11.24 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||||
|
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||||
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
|
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||||
|
github.com/beevik/etree v1.1.0 // indirect
|
||||||
|
github.com/bradleyfalzon/tlsx v0.0.0-20170624122154-28fd0e59bac4 // indirect
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
|
||||||
|
github.com/chanced/dynamic v0.0.0-20211210164248-f8fadb1d735b // indirect
|
||||||
|
github.com/cilium/ebpf v0.8.0 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||||
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||||
|
github.com/fatih/camelcase v1.0.0 // indirect
|
||||||
|
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||||
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
|
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||||
|
github.com/go-errors/errors v1.4.2 // indirect
|
||||||
|
github.com/go-logr/logr v1.2.2 // indirect
|
||||||
|
github.com/go-openapi/analysis v0.21.2 // indirect
|
||||||
|
github.com/go-openapi/errors v0.20.2 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
|
github.com/go-openapi/loads v0.21.1 // indirect
|
||||||
|
github.com/go-openapi/runtime v0.23.0 // indirect
|
||||||
|
github.com/go-openapi/spec v0.20.4 // indirect
|
||||||
|
github.com/go-openapi/strfmt v0.21.2 // indirect
|
||||||
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
|
github.com/go-openapi/validate v0.20.3 // indirect
|
||||||
|
github.com/go-stack/stack v1.8.1 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/golang/snappy v0.0.4 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.7 // indirect
|
||||||
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
github.com/google/gopacket v1.1.19 // indirect
|
||||||
|
github.com/google/martian v2.1.0+incompatible // indirect
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/klauspost/compress v1.14.2 // indirect
|
||||||
|
github.com/leodido/go-urn v1.2.1 // indirect
|
||||||
|
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||||
|
github.com/moby/spdystream v0.2.0 // indirect
|
||||||
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
|
github.com/ohler55/ojg v1.12.12 // indirect
|
||||||
|
github.com/oklog/ulid v1.3.1 // indirect
|
||||||
|
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||||
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
|
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/russross/blackfriday v1.6.0 // indirect
|
||||||
|
github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect
|
||||||
|
github.com/segmentio/kafka-go v0.4.27 // indirect
|
||||||
|
github.com/spf13/cobra v1.3.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/tidwall/gjson v1.14.0 // indirect
|
||||||
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
|
github.com/tidwall/pretty v1.2.0 // indirect
|
||||||
|
github.com/tidwall/sjson v1.2.4 // indirect
|
||||||
|
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||||
|
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
|
||||||
|
github.com/xlab/treeprint v1.1.0 // indirect
|
||||||
|
go.mongodb.org/mongo-driver v1.8.3 // indirect
|
||||||
|
go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||||
|
k8s.io/cli-runtime v0.23.3 // indirect
|
||||||
|
k8s.io/component-base v0.23.3 // indirect
|
||||||
|
k8s.io/klog/v2 v2.40.1 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||||
|
k8s.io/kubectl v0.23.3 // indirect
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||||
|
sigs.k8s.io/kustomize/api v0.11.1 // indirect
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.13.3 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
||||||
|
|||||||
707
agent/go.sum
707
agent/go.sum
File diff suppressed because it is too large
Load Diff
312
agent/main.go
312
agent/main.go
@@ -9,12 +9,14 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/static"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/elastic"
|
||||||
"github.com/up9inc/mizu/agent/pkg/middlewares"
|
"github.com/up9inc/mizu/agent/pkg/middlewares"
|
||||||
"github.com/up9inc/mizu/agent/pkg/models"
|
"github.com/up9inc/mizu/agent/pkg/models"
|
||||||
"github.com/up9inc/mizu/agent/pkg/oas"
|
"github.com/up9inc/mizu/agent/pkg/oas"
|
||||||
@@ -23,30 +25,18 @@ import (
|
|||||||
"github.com/up9inc/mizu/agent/pkg/up9"
|
"github.com/up9inc/mizu/agent/pkg/up9"
|
||||||
"github.com/up9inc/mizu/agent/pkg/utils"
|
"github.com/up9inc/mizu/agent/pkg/utils"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/agent/pkg/elastic"
|
|
||||||
|
|
||||||
"github.com/up9inc/mizu/agent/pkg/controllers"
|
|
||||||
|
|
||||||
"github.com/up9inc/mizu/agent/pkg/api"
|
"github.com/up9inc/mizu/agent/pkg/api"
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/app"
|
||||||
"github.com/up9inc/mizu/agent/pkg/config"
|
"github.com/up9inc/mizu/agent/pkg/config"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
|
||||||
"github.com/antelman107/net-wait-go/wait"
|
|
||||||
"github.com/gin-contrib/static"
|
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"github.com/gorilla/websocket"
|
"github.com/gorilla/websocket"
|
||||||
"github.com/op/go-logging"
|
"github.com/op/go-logging"
|
||||||
basenine "github.com/up9inc/basenine/client/go"
|
|
||||||
"github.com/up9inc/mizu/shared"
|
"github.com/up9inc/mizu/shared"
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
"github.com/up9inc/mizu/tap"
|
"github.com/up9inc/mizu/tap"
|
||||||
tapApi "github.com/up9inc/mizu/tap/api"
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
|
|
||||||
amqpExt "github.com/up9inc/mizu/tap/extensions/amqp"
|
|
||||||
httpExt "github.com/up9inc/mizu/tap/extensions/http"
|
|
||||||
kafkaExt "github.com/up9inc/mizu/tap/extensions/kafka"
|
|
||||||
redisExt "github.com/up9inc/mizu/tap/extensions/redis"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var tapperMode = flag.Bool("tap", false, "Run in tapper mode without API")
|
var tapperMode = flag.Bool("tap", false, "Run in tapper mode without API")
|
||||||
@@ -56,10 +46,6 @@ var apiServerAddress = flag.String("api-server-address", "", "Address of mizu AP
|
|||||||
var namespace = flag.String("namespace", "", "Resolve IPs if they belong to resources in this namespace (default is all)")
|
var namespace = flag.String("namespace", "", "Resolve IPs if they belong to resources in this namespace (default is all)")
|
||||||
var harsReaderMode = flag.Bool("hars-read", false, "Run in hars-read mode")
|
var harsReaderMode = flag.Bool("hars-read", false, "Run in hars-read mode")
|
||||||
var harsDir = flag.String("hars-dir", "", "Directory to read hars from")
|
var harsDir = flag.String("hars-dir", "", "Directory to read hars from")
|
||||||
|
|
||||||
var extensions []*tapApi.Extension // global
|
|
||||||
var extensionsMap map[string]*tapApi.Extension // global
|
|
||||||
|
|
||||||
var startTime int64
|
var startTime int64
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -70,83 +56,23 @@ const (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
logLevel := determineLogLevel()
|
logLevel := determineLogLevel()
|
||||||
logger.InitLoggerStderrOnly(logLevel)
|
logger.InitLoggerStd(logLevel)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if err := config.LoadConfig(); err != nil {
|
|
||||||
logger.Log.Fatalf("Error loading config file %v", err)
|
app.LoadExtensions()
|
||||||
}
|
|
||||||
loadExtensions()
|
|
||||||
|
|
||||||
if !*tapperMode && !*apiServerMode && !*standaloneMode && !*harsReaderMode {
|
if !*tapperMode && !*apiServerMode && !*standaloneMode && !*harsReaderMode {
|
||||||
panic("One of the flags --tap, --api or --standalone or --hars-read must be provided")
|
panic("One of the flags --tap, --api or --standalone or --hars-read must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *standaloneMode {
|
if *standaloneMode {
|
||||||
api.StartResolving(*namespace)
|
runInStandaloneMode()
|
||||||
|
|
||||||
outputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
|
|
||||||
filteringOptions := getTrafficFilteringOptions()
|
|
||||||
hostMode := os.Getenv(shared.HostModeEnvVar) == "1"
|
|
||||||
tapOpts := &tap.TapOpts{HostMode: hostMode}
|
|
||||||
tap.StartPassiveTapper(tapOpts, outputItemsChannel, extensions, filteringOptions)
|
|
||||||
|
|
||||||
go filterItems(outputItemsChannel, filteredOutputItemsChannel)
|
|
||||||
go api.StartReadingEntries(filteredOutputItemsChannel, nil, extensionsMap)
|
|
||||||
|
|
||||||
hostApi(nil)
|
|
||||||
} else if *tapperMode {
|
} else if *tapperMode {
|
||||||
logger.Log.Infof("Starting tapper, websocket address: %s", *apiServerAddress)
|
runInTapperMode()
|
||||||
if *apiServerAddress == "" {
|
|
||||||
panic("API server address must be provided with --api-server-address when using --tap")
|
|
||||||
}
|
|
||||||
|
|
||||||
hostMode := os.Getenv(shared.HostModeEnvVar) == "1"
|
|
||||||
tapOpts := &tap.TapOpts{HostMode: hostMode}
|
|
||||||
tapTargets := getTapTargets()
|
|
||||||
if tapTargets != nil {
|
|
||||||
tapOpts.FilterAuthorities = tapTargets
|
|
||||||
logger.Log.Infof("Filtering for the following authorities: %v", tapOpts.FilterAuthorities)
|
|
||||||
}
|
|
||||||
|
|
||||||
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
|
|
||||||
filteringOptions := getTrafficFilteringOptions()
|
|
||||||
tap.StartPassiveTapper(tapOpts, filteredOutputItemsChannel, extensions, filteringOptions)
|
|
||||||
socketConnection, err := dialSocketWithRetry(*apiServerAddress, socketConnectionRetries, socketConnectionRetryDelay)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("Error connecting to socket server at %s %v", *apiServerAddress, err))
|
|
||||||
}
|
|
||||||
logger.Log.Infof("Connected successfully to websocket %s", *apiServerAddress)
|
|
||||||
|
|
||||||
go pipeTapChannelToSocket(socketConnection, filteredOutputItemsChannel)
|
|
||||||
} else if *apiServerMode {
|
} else if *apiServerMode {
|
||||||
configureBasenineServer(shared.BasenineHost, shared.BaseninePort)
|
utils.StartServer(runInApiServerMode(*namespace))
|
||||||
startTime = time.Now().UnixNano() / int64(time.Millisecond)
|
|
||||||
api.StartResolving(*namespace)
|
|
||||||
|
|
||||||
outputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
enableExpFeatureIfNeeded()
|
|
||||||
go filterItems(outputItemsChannel, filteredOutputItemsChannel)
|
|
||||||
go api.StartReadingEntries(filteredOutputItemsChannel, nil, extensionsMap)
|
|
||||||
|
|
||||||
syncEntriesConfig := getSyncEntriesConfig()
|
|
||||||
if syncEntriesConfig != nil {
|
|
||||||
if err := up9.SyncEntries(syncEntriesConfig); err != nil {
|
|
||||||
logger.Log.Error("Error syncing entries, err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hostApi(outputItemsChannel)
|
|
||||||
} else if *harsReaderMode {
|
} else if *harsReaderMode {
|
||||||
outputItemsChannel := make(chan *tapApi.OutputChannelItem, 1000)
|
runInHarReaderMode()
|
||||||
filteredHarChannel := make(chan *tapApi.OutputChannelItem)
|
|
||||||
|
|
||||||
go filterItems(outputItemsChannel, filteredHarChannel)
|
|
||||||
go api.StartReadingEntries(filteredHarChannel, harsDir, extensionsMap)
|
|
||||||
hostApi(nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
signalChan := make(chan os.Signal, 1)
|
signalChan := make(chan os.Signal, 1)
|
||||||
@@ -156,89 +82,7 @@ func main() {
|
|||||||
logger.Log.Info("Exiting")
|
logger.Log.Info("Exiting")
|
||||||
}
|
}
|
||||||
|
|
||||||
func enableExpFeatureIfNeeded() {
|
func hostApi(socketHarOutputChannel chan<- *tapApi.OutputChannelItem) *gin.Engine {
|
||||||
if config.Config.OAS {
|
|
||||||
oas.GetOasGeneratorInstance().Start()
|
|
||||||
}
|
|
||||||
if config.Config.ServiceMap {
|
|
||||||
servicemap.GetInstance().SetConfig(config.Config)
|
|
||||||
}
|
|
||||||
elastic.GetInstance().Configure(config.Config.Elastic)
|
|
||||||
}
|
|
||||||
|
|
||||||
func configureBasenineServer(host string, port string) {
|
|
||||||
if !wait.New(
|
|
||||||
wait.WithProto("tcp"),
|
|
||||||
wait.WithWait(200*time.Millisecond),
|
|
||||||
wait.WithBreak(50*time.Millisecond),
|
|
||||||
wait.WithDeadline(5*time.Second),
|
|
||||||
wait.WithDebug(config.Config.LogLevel == logging.DEBUG),
|
|
||||||
).Do([]string{fmt.Sprintf("%s:%s", host, port)}) {
|
|
||||||
logger.Log.Panicf("Basenine is not available!")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Limit the database size to default 200MB
|
|
||||||
err := basenine.Limit(host, port, config.Config.MaxDBSizeBytes)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log.Panicf("Error while limiting database size: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define the macros
|
|
||||||
for _, extension := range extensions {
|
|
||||||
macros := extension.Dissector.Macros()
|
|
||||||
for macro, expanded := range macros {
|
|
||||||
err = basenine.Macro(host, port, macro, expanded)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log.Panicf("Error while adding a macro: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadExtensions() {
|
|
||||||
extensions = make([]*tapApi.Extension, 4)
|
|
||||||
extensionsMap = make(map[string]*tapApi.Extension)
|
|
||||||
|
|
||||||
extensionAmqp := &tapApi.Extension{}
|
|
||||||
dissectorAmqp := amqpExt.NewDissector()
|
|
||||||
dissectorAmqp.Register(extensionAmqp)
|
|
||||||
extensionAmqp.Dissector = dissectorAmqp
|
|
||||||
extensions[0] = extensionAmqp
|
|
||||||
extensionsMap[extensionAmqp.Protocol.Name] = extensionAmqp
|
|
||||||
|
|
||||||
extensionHttp := &tapApi.Extension{}
|
|
||||||
dissectorHttp := httpExt.NewDissector()
|
|
||||||
dissectorHttp.Register(extensionHttp)
|
|
||||||
extensionHttp.Dissector = dissectorHttp
|
|
||||||
extensions[1] = extensionHttp
|
|
||||||
extensionsMap[extensionHttp.Protocol.Name] = extensionHttp
|
|
||||||
|
|
||||||
extensionKafka := &tapApi.Extension{}
|
|
||||||
dissectorKafka := kafkaExt.NewDissector()
|
|
||||||
dissectorKafka.Register(extensionKafka)
|
|
||||||
extensionKafka.Dissector = dissectorKafka
|
|
||||||
extensions[2] = extensionKafka
|
|
||||||
extensionsMap[extensionKafka.Protocol.Name] = extensionKafka
|
|
||||||
|
|
||||||
extensionRedis := &tapApi.Extension{}
|
|
||||||
dissectorRedis := redisExt.NewDissector()
|
|
||||||
dissectorRedis.Register(extensionRedis)
|
|
||||||
extensionRedis.Dissector = dissectorRedis
|
|
||||||
extensions[3] = extensionRedis
|
|
||||||
extensionsMap[extensionRedis.Protocol.Name] = extensionRedis
|
|
||||||
|
|
||||||
sort.Slice(extensions, func(i, j int) bool {
|
|
||||||
return extensions[i].Protocol.Priority < extensions[j].Protocol.Priority
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, extension := range extensions {
|
|
||||||
logger.Log.Infof("Extension Properties: %+v", extension)
|
|
||||||
}
|
|
||||||
|
|
||||||
controllers.InitExtensionsMap(extensionsMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
func hostApi(socketHarOutputChannel chan<- *tapApi.OutputChannelItem) {
|
|
||||||
app := gin.Default()
|
app := gin.Default()
|
||||||
|
|
||||||
app.GET("/echo", func(c *gin.Context) {
|
app.GET("/echo", func(c *gin.Context) {
|
||||||
@@ -249,7 +93,7 @@ func hostApi(socketHarOutputChannel chan<- *tapApi.OutputChannelItem) {
|
|||||||
SocketOutChannel: socketHarOutputChannel,
|
SocketOutChannel: socketHarOutputChannel,
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Use(DisableRootStaticCache())
|
app.Use(disableRootStaticCache())
|
||||||
|
|
||||||
var staticFolder string
|
var staticFolder string
|
||||||
if config.Config.StandaloneMode {
|
if config.Config.StandaloneMode {
|
||||||
@@ -288,10 +132,111 @@ func hostApi(socketHarOutputChannel chan<- *tapApi.OutputChannelItem) {
|
|||||||
routes.EntriesRoutes(app)
|
routes.EntriesRoutes(app)
|
||||||
routes.MetadataRoutes(app)
|
routes.MetadataRoutes(app)
|
||||||
routes.StatusRoutes(app)
|
routes.StatusRoutes(app)
|
||||||
utils.StartServer(app)
|
|
||||||
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
func DisableRootStaticCache() gin.HandlerFunc {
|
func runInApiServerMode(namespace string) *gin.Engine {
|
||||||
|
if err := config.LoadConfig(); err != nil {
|
||||||
|
logger.Log.Fatalf("Error loading config file %v", err)
|
||||||
|
}
|
||||||
|
app.ConfigureBasenineServer(shared.BasenineHost, shared.BaseninePort, config.Config.MaxDBSizeBytes, config.Config.LogLevel, config.Config.InsertionFilter)
|
||||||
|
startTime = time.Now().UnixNano() / int64(time.Millisecond)
|
||||||
|
api.StartResolving(namespace)
|
||||||
|
|
||||||
|
enableExpFeatureIfNeeded()
|
||||||
|
|
||||||
|
syncEntriesConfig := getSyncEntriesConfig()
|
||||||
|
if syncEntriesConfig != nil {
|
||||||
|
if err := up9.SyncEntries(syncEntriesConfig); err != nil {
|
||||||
|
logger.Log.Error("Error syncing entries, err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostApi(app.GetEntryInputChannel())
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInTapperMode() {
|
||||||
|
logger.Log.Infof("Starting tapper, websocket address: %s", *apiServerAddress)
|
||||||
|
if *apiServerAddress == "" {
|
||||||
|
panic("API server address must be provided with --api-server-address when using --tap")
|
||||||
|
}
|
||||||
|
|
||||||
|
hostMode := os.Getenv(shared.HostModeEnvVar) == "1"
|
||||||
|
tapOpts := &tap.TapOpts{HostMode: hostMode}
|
||||||
|
tapTargets := getTapTargets()
|
||||||
|
if tapTargets != nil {
|
||||||
|
tapOpts.FilterAuthorities = tapTargets
|
||||||
|
logger.Log.Infof("Filtering for the following authorities: %v", tapOpts.FilterAuthorities)
|
||||||
|
}
|
||||||
|
|
||||||
|
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
|
||||||
|
filteringOptions := getTrafficFilteringOptions()
|
||||||
|
tap.StartPassiveTapper(tapOpts, filteredOutputItemsChannel, app.Extensions, filteringOptions)
|
||||||
|
socketConnection, err := dialSocketWithRetry(*apiServerAddress, socketConnectionRetries, socketConnectionRetryDelay)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("Error connecting to socket server at %s %v", *apiServerAddress, err))
|
||||||
|
}
|
||||||
|
logger.Log.Infof("Connected successfully to websocket %s", *apiServerAddress)
|
||||||
|
|
||||||
|
go pipeTapChannelToSocket(socketConnection, filteredOutputItemsChannel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInStandaloneMode() {
|
||||||
|
api.StartResolving(*namespace)
|
||||||
|
|
||||||
|
outputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
|
||||||
|
filteringOptions := getTrafficFilteringOptions()
|
||||||
|
hostMode := os.Getenv(shared.HostModeEnvVar) == "1"
|
||||||
|
tapOpts := &tap.TapOpts{HostMode: hostMode}
|
||||||
|
tap.StartPassiveTapper(tapOpts, outputItemsChannel, app.Extensions, filteringOptions)
|
||||||
|
|
||||||
|
go app.FilterItems(outputItemsChannel, filteredOutputItemsChannel)
|
||||||
|
go api.StartReadingEntries(filteredOutputItemsChannel, nil, app.ExtensionsMap)
|
||||||
|
|
||||||
|
ginApp := hostApi(nil)
|
||||||
|
utils.StartServer(ginApp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runInHarReaderMode() {
|
||||||
|
outputItemsChannel := make(chan *tapApi.OutputChannelItem, 1000)
|
||||||
|
filteredHarChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
|
||||||
|
go app.FilterItems(outputItemsChannel, filteredHarChannel)
|
||||||
|
go api.StartReadingEntries(filteredHarChannel, harsDir, app.ExtensionsMap)
|
||||||
|
ginApp := hostApi(nil)
|
||||||
|
utils.StartServer(ginApp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func enableExpFeatureIfNeeded() {
|
||||||
|
if config.Config.OAS {
|
||||||
|
oas.GetOasGeneratorInstance().Start()
|
||||||
|
}
|
||||||
|
if config.Config.ServiceMap {
|
||||||
|
servicemap.GetInstance().Enable()
|
||||||
|
}
|
||||||
|
elastic.GetInstance().Configure(config.Config.Elastic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSyncEntriesConfig() *shared.SyncEntriesConfig {
|
||||||
|
syncEntriesConfigJson := os.Getenv(shared.SyncEntriesConfigEnvVar)
|
||||||
|
if syncEntriesConfigJson == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var syncEntriesConfig = &shared.SyncEntriesConfig{}
|
||||||
|
err := json.Unmarshal([]byte(syncEntriesConfigJson), syncEntriesConfig)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("env var %s's value of %s is invalid! json must match the shared.SyncEntriesConfig struct, err: %v", shared.SyncEntriesConfigEnvVar, syncEntriesConfigJson, err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return syncEntriesConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func disableRootStaticCache() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
if c.Request.RequestURI == "/" {
|
if c.Request.RequestURI == "/" {
|
||||||
// Disable cache only for the main static route
|
// Disable cache only for the main static route
|
||||||
@@ -357,16 +302,6 @@ func getTrafficFilteringOptions() *tapApi.TrafficFilteringOptions {
|
|||||||
return &filteringOptions
|
return &filteringOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterItems(inChannel <-chan *tapApi.OutputChannelItem, outChannel chan *tapApi.OutputChannelItem) {
|
|
||||||
for message := range inChannel {
|
|
||||||
if message.ConnectionInfo.IsOutgoing && api.CheckIsServiceIP(message.ConnectionInfo.ServerIP) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
outChannel <- message
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func pipeTapChannelToSocket(connection *websocket.Conn, messageDataChannel <-chan *tapApi.OutputChannelItem) {
|
func pipeTapChannelToSocket(connection *websocket.Conn, messageDataChannel <-chan *tapApi.OutputChannelItem) {
|
||||||
if connection == nil {
|
if connection == nil {
|
||||||
panic("Websocket connection is nil")
|
panic("Websocket connection is nil")
|
||||||
@@ -402,21 +337,6 @@ func pipeTapChannelToSocket(connection *websocket.Conn, messageDataChannel <-cha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSyncEntriesConfig() *shared.SyncEntriesConfig {
|
|
||||||
syncEntriesConfigJson := os.Getenv(shared.SyncEntriesConfigEnvVar)
|
|
||||||
if syncEntriesConfigJson == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var syncEntriesConfig = &shared.SyncEntriesConfig{}
|
|
||||||
err := json.Unmarshal([]byte(syncEntriesConfigJson), syncEntriesConfig)
|
|
||||||
if err != nil {
|
|
||||||
panic(fmt.Sprintf("env var %s's value of %s is invalid! json must match the shared.SyncEntriesConfig struct, err: %v", shared.SyncEntriesConfigEnvVar, syncEntriesConfigJson, err))
|
|
||||||
}
|
|
||||||
|
|
||||||
return syncEntriesConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
func determineLogLevel() (logLevel logging.Level) {
|
func determineLogLevel() (logLevel logging.Level) {
|
||||||
logLevel, err := logging.LogLevel(os.Getenv(shared.LogLevelEnvVar))
|
logLevel, err := logging.LogLevel(os.Getenv(shared.LogLevelEnvVar))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -118,8 +118,8 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
|
|||||||
|
|
||||||
for item := range outputItems {
|
for item := range outputItems {
|
||||||
extension := extensionsMap[item.Protocol.Name]
|
extension := extensionsMap[item.Protocol.Name]
|
||||||
resolvedSource, resolvedDestionation := resolveIP(item.ConnectionInfo)
|
resolvedSource, resolvedDestionation, namespace := resolveIP(item.ConnectionInfo)
|
||||||
mizuEntry := extension.Dissector.Analyze(item, resolvedSource, resolvedDestionation)
|
mizuEntry := extension.Dissector.Analyze(item, resolvedSource, resolvedDestionation, namespace)
|
||||||
if extension.Protocol.Name == "http" {
|
if extension.Protocol.Name == "http" {
|
||||||
if !disableOASValidation {
|
if !disableOASValidation {
|
||||||
var httpPair tapApi.HTTPRequestResponsePair
|
var httpPair tapApi.HTTPRequestResponsePair
|
||||||
@@ -140,7 +140,17 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
|
|||||||
mizuEntry.Rules = rules
|
mizuEntry.Rules = rules
|
||||||
}
|
}
|
||||||
|
|
||||||
entryWSource := oas.EntryWithSource{Entry: *harEntry, Source: mizuEntry.Source.Name}
|
entryWSource := oas.EntryWithSource{
|
||||||
|
Entry: *harEntry,
|
||||||
|
Source: mizuEntry.Source.Name,
|
||||||
|
Destination: mizuEntry.Destination.Name,
|
||||||
|
Id: mizuEntry.Id,
|
||||||
|
}
|
||||||
|
|
||||||
|
if entryWSource.Destination == "" {
|
||||||
|
entryWSource.Destination = mizuEntry.Destination.IP + ":" + mizuEntry.Destination.Port
|
||||||
|
}
|
||||||
|
|
||||||
oas.GetOasGeneratorInstance().PushEntry(&entryWSource)
|
oas.GetOasGeneratorInstance().PushEntry(&entryWSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,26 +168,32 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolveIP(connectionInfo *tapApi.ConnectionInfo) (resolvedSource string, resolvedDestination string) {
|
func resolveIP(connectionInfo *tapApi.ConnectionInfo) (resolvedSource string, resolvedDestination string, namespace string) {
|
||||||
if k8sResolver != nil {
|
if k8sResolver != nil {
|
||||||
unresolvedSource := connectionInfo.ClientIP
|
unresolvedSource := connectionInfo.ClientIP
|
||||||
resolvedSource = k8sResolver.Resolve(unresolvedSource)
|
resolvedSourceObject := k8sResolver.Resolve(unresolvedSource)
|
||||||
if resolvedSource == "" {
|
if resolvedSourceObject == nil {
|
||||||
logger.Log.Debugf("Cannot find resolved name to source: %s", unresolvedSource)
|
logger.Log.Debugf("Cannot find resolved name to source: %s", unresolvedSource)
|
||||||
if os.Getenv("SKIP_NOT_RESOLVED_SOURCE") == "1" {
|
if os.Getenv("SKIP_NOT_RESOLVED_SOURCE") == "1" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
resolvedSource = resolvedSourceObject.FullAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
unresolvedDestination := fmt.Sprintf("%s:%s", connectionInfo.ServerIP, connectionInfo.ServerPort)
|
unresolvedDestination := fmt.Sprintf("%s:%s", connectionInfo.ServerIP, connectionInfo.ServerPort)
|
||||||
resolvedDestination = k8sResolver.Resolve(unresolvedDestination)
|
resolvedDestinationObject := k8sResolver.Resolve(unresolvedDestination)
|
||||||
if resolvedDestination == "" {
|
if resolvedDestinationObject == nil {
|
||||||
logger.Log.Debugf("Cannot find resolved name to dest: %s", unresolvedDestination)
|
logger.Log.Debugf("Cannot find resolved name to dest: %s", unresolvedDestination)
|
||||||
if os.Getenv("SKIP_NOT_RESOLVED_DEST") == "1" {
|
if os.Getenv("SKIP_NOT_RESOLVED_DEST") == "1" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
resolvedDestination = resolvedDestinationObject.FullAddress
|
||||||
|
namespace = resolvedDestinationObject.Namespace
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolvedSource, resolvedDestination
|
return resolvedSource, resolvedDestination, namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
func CheckIsServiceIP(address string) bool {
|
func CheckIsServiceIP(address string) bool {
|
||||||
|
|||||||
@@ -30,14 +30,23 @@ type SocketConnection struct {
|
|||||||
isTapper bool
|
isTapper bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var websocketUpgrader = websocket.Upgrader{
|
type WebSocketParams struct {
|
||||||
ReadBufferSize: 1024,
|
Query string `json:"query"`
|
||||||
WriteBufferSize: 1024,
|
EnableFullEntries bool `json:"enableFullEntries"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var websocketIdsLock = sync.Mutex{}
|
var (
|
||||||
var connectedWebsockets map[int]*SocketConnection
|
websocketUpgrader = websocket.Upgrader{
|
||||||
var connectedWebsocketIdCounter = 0
|
ReadBufferSize: 1024,
|
||||||
|
WriteBufferSize: 1024,
|
||||||
|
}
|
||||||
|
|
||||||
|
websocketIdsLock = sync.Mutex{}
|
||||||
|
connectedWebsockets map[int]*SocketConnection
|
||||||
|
connectedWebsocketIdCounter = 0
|
||||||
|
SocketGetBrowserHandler gin.HandlerFunc
|
||||||
|
SocketGetTapperHandler gin.HandlerFunc
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
websocketUpgrader.CheckOrigin = func(r *http.Request) bool { return true } // like cors for web socket
|
websocketUpgrader.CheckOrigin = func(r *http.Request) bool { return true } // like cors for web socket
|
||||||
@@ -45,12 +54,20 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func WebSocketRoutes(app *gin.Engine, eventHandlers EventHandlers, startTime int64) {
|
func WebSocketRoutes(app *gin.Engine, eventHandlers EventHandlers, startTime int64) {
|
||||||
app.GET("/ws", func(c *gin.Context) {
|
SocketGetBrowserHandler = func(c *gin.Context) {
|
||||||
websocketHandler(c.Writer, c.Request, eventHandlers, false, startTime)
|
websocketHandler(c.Writer, c.Request, eventHandlers, false, startTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketGetTapperHandler = func(c *gin.Context) {
|
||||||
|
websocketHandler(c.Writer, c.Request, eventHandlers, true, startTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
app.GET("/ws", func(c *gin.Context) {
|
||||||
|
SocketGetBrowserHandler(c)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.GET("/wsTapper", func(c *gin.Context) { // TODO: add m2m authentication to this route
|
app.GET("/wsTapper", func(c *gin.Context) { // TODO: add m2m authentication to this route
|
||||||
websocketHandler(c.Writer, c.Request, eventHandlers, true, startTime)
|
SocketGetTapperHandler(c)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +115,8 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
|||||||
logger.Log.Error(err)
|
logger.Log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var params WebSocketParams
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, msg, err := ws.ReadMessage()
|
_, msg, err := ws.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -111,7 +130,11 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isTapper && !isQuerySet {
|
if !isTapper && !isQuerySet {
|
||||||
query := string(msg)
|
if err := json.Unmarshal(msg, ¶ms); err != nil {
|
||||||
|
logger.Log.Errorf("Error: %v", socketId, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
query := params.Query
|
||||||
err = basenine.Validate(shared.BasenineHost, shared.BaseninePort, query)
|
err = basenine.Validate(shared.BasenineHost, shared.BaseninePort, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
toastBytes, _ := models.CreateWebsocketToastMessage(&models.ToastMessage{
|
toastBytes, _ := models.CreateWebsocketToastMessage(&models.ToastMessage{
|
||||||
@@ -138,10 +161,15 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
|
|||||||
var entry *tapApi.Entry
|
var entry *tapApi.Entry
|
||||||
err = json.Unmarshal(bytes, &entry)
|
err = json.Unmarshal(bytes, &entry)
|
||||||
|
|
||||||
base := tapApi.Summarize(entry)
|
var message []byte
|
||||||
|
if params.EnableFullEntries {
|
||||||
|
message, _ = models.CreateFullEntryWebSocketMessage(entry)
|
||||||
|
} else {
|
||||||
|
base := tapApi.Summarize(entry)
|
||||||
|
message, _ = models.CreateBaseEntryWebSocketMessage(base)
|
||||||
|
}
|
||||||
|
|
||||||
baseEntryBytes, _ := models.CreateBaseEntryWebSocketMessage(base)
|
if err := SendToSocket(socketId, message); err != nil {
|
||||||
if err := SendToSocket(socketId, baseEntryBytes); err != nil {
|
|
||||||
logger.Log.Error(err)
|
logger.Log.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,9 +34,12 @@ func (h *RoutesEventHandlers) WebSocketConnect(socketId int, isTapper bool) {
|
|||||||
tappers.Connected()
|
tappers.Connected()
|
||||||
} else {
|
} else {
|
||||||
logger.Log.Infof("Websocket event - Browser socket connected, socket ID: %d", socketId)
|
logger.Log.Infof("Websocket event - Browser socket connected, socket ID: %d", socketId)
|
||||||
|
|
||||||
socketListLock.Lock()
|
socketListLock.Lock()
|
||||||
browserClientSocketUUIDs = append(browserClientSocketUUIDs, socketId)
|
browserClientSocketUUIDs = append(browserClientSocketUUIDs, socketId)
|
||||||
socketListLock.Unlock()
|
socketListLock.Unlock()
|
||||||
|
|
||||||
|
BroadcastTappedPodsStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,9 +104,9 @@ func (h *RoutesEventHandlers) WebSocketMessage(_ int, message []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleTLSLink(outboundLinkMessage models.WebsocketOutboundLinkMessage) {
|
func handleTLSLink(outboundLinkMessage models.WebsocketOutboundLinkMessage) {
|
||||||
resolvedName := k8sResolver.Resolve(outboundLinkMessage.Data.DstIP)
|
resolvedNameObject := k8sResolver.Resolve(outboundLinkMessage.Data.DstIP)
|
||||||
if resolvedName != "" {
|
if resolvedNameObject != nil {
|
||||||
outboundLinkMessage.Data.DstIP = resolvedName
|
outboundLinkMessage.Data.DstIP = resolvedNameObject.FullAddress
|
||||||
} else if outboundLinkMessage.Data.SuggestedResolvedName != "" {
|
} else if outboundLinkMessage.Data.SuggestedResolvedName != "" {
|
||||||
outboundLinkMessage.Data.DstIP = outboundLinkMessage.Data.SuggestedResolvedName
|
outboundLinkMessage.Data.DstIP = outboundLinkMessage.Data.SuggestedResolvedName
|
||||||
}
|
}
|
||||||
|
|||||||
20
agent/pkg/api/utils.go
Normal file
20
agent/pkg/api/utils.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/providers/tappedPods"
|
||||||
|
"github.com/up9inc/mizu/shared"
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BroadcastTappedPodsStatus() {
|
||||||
|
tappedPodsStatus := tappedPods.GetTappedPodsStatus()
|
||||||
|
|
||||||
|
message := shared.CreateWebSocketStatusMessage(tappedPodsStatus)
|
||||||
|
if jsonBytes, err := json.Marshal(message); err != nil {
|
||||||
|
logger.Log.Errorf("Could not Marshal message %v", err)
|
||||||
|
} else {
|
||||||
|
BroadcastToBrowserClients(jsonBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
113
agent/pkg/app/main.go
Normal file
113
agent/pkg/app/main.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/antelman107/net-wait-go/wait"
|
||||||
|
"github.com/op/go-logging"
|
||||||
|
basenine "github.com/up9inc/basenine/client/go"
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/api"
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/controllers"
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
|
amqpExt "github.com/up9inc/mizu/tap/extensions/amqp"
|
||||||
|
httpExt "github.com/up9inc/mizu/tap/extensions/http"
|
||||||
|
kafkaExt "github.com/up9inc/mizu/tap/extensions/kafka"
|
||||||
|
redisExt "github.com/up9inc/mizu/tap/extensions/redis"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
Extensions []*tapApi.Extension // global
|
||||||
|
ExtensionsMap map[string]*tapApi.Extension // global
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadExtensions() {
|
||||||
|
Extensions = make([]*tapApi.Extension, 4)
|
||||||
|
ExtensionsMap = make(map[string]*tapApi.Extension)
|
||||||
|
|
||||||
|
extensionAmqp := &tapApi.Extension{}
|
||||||
|
dissectorAmqp := amqpExt.NewDissector()
|
||||||
|
dissectorAmqp.Register(extensionAmqp)
|
||||||
|
extensionAmqp.Dissector = dissectorAmqp
|
||||||
|
Extensions[0] = extensionAmqp
|
||||||
|
ExtensionsMap[extensionAmqp.Protocol.Name] = extensionAmqp
|
||||||
|
|
||||||
|
extensionHttp := &tapApi.Extension{}
|
||||||
|
dissectorHttp := httpExt.NewDissector()
|
||||||
|
dissectorHttp.Register(extensionHttp)
|
||||||
|
extensionHttp.Dissector = dissectorHttp
|
||||||
|
Extensions[1] = extensionHttp
|
||||||
|
ExtensionsMap[extensionHttp.Protocol.Name] = extensionHttp
|
||||||
|
|
||||||
|
extensionKafka := &tapApi.Extension{}
|
||||||
|
dissectorKafka := kafkaExt.NewDissector()
|
||||||
|
dissectorKafka.Register(extensionKafka)
|
||||||
|
extensionKafka.Dissector = dissectorKafka
|
||||||
|
Extensions[2] = extensionKafka
|
||||||
|
ExtensionsMap[extensionKafka.Protocol.Name] = extensionKafka
|
||||||
|
|
||||||
|
extensionRedis := &tapApi.Extension{}
|
||||||
|
dissectorRedis := redisExt.NewDissector()
|
||||||
|
dissectorRedis.Register(extensionRedis)
|
||||||
|
extensionRedis.Dissector = dissectorRedis
|
||||||
|
Extensions[3] = extensionRedis
|
||||||
|
ExtensionsMap[extensionRedis.Protocol.Name] = extensionRedis
|
||||||
|
|
||||||
|
sort.Slice(Extensions, func(i, j int) bool {
|
||||||
|
return Extensions[i].Protocol.Priority < Extensions[j].Protocol.Priority
|
||||||
|
})
|
||||||
|
|
||||||
|
controllers.InitExtensionsMap(ExtensionsMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConfigureBasenineServer(host string, port string, dbSize int64, logLevel logging.Level, insertionFilter string) {
|
||||||
|
if !wait.New(
|
||||||
|
wait.WithProto("tcp"),
|
||||||
|
wait.WithWait(200*time.Millisecond),
|
||||||
|
wait.WithBreak(50*time.Millisecond),
|
||||||
|
wait.WithDeadline(5*time.Second),
|
||||||
|
wait.WithDebug(logLevel == logging.DEBUG),
|
||||||
|
).Do([]string{fmt.Sprintf("%s:%s", host, port)}) {
|
||||||
|
logger.Log.Panicf("Basenine is not available!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := basenine.Limit(host, port, dbSize); err != nil {
|
||||||
|
logger.Log.Panicf("Error while limiting database size: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the macros
|
||||||
|
for _, extension := range Extensions {
|
||||||
|
macros := extension.Dissector.Macros()
|
||||||
|
for macro, expanded := range macros {
|
||||||
|
if err := basenine.Macro(host, port, macro, expanded); err != nil {
|
||||||
|
logger.Log.Panicf("Error while adding a macro: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the insertion filter that comes from the config
|
||||||
|
if err := basenine.InsertionFilter(host, port, insertionFilter); err != nil {
|
||||||
|
logger.Log.Errorf("Error while setting the insertion filter: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEntryInputChannel() chan *tapApi.OutputChannelItem {
|
||||||
|
outputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
filteredOutputItemsChannel := make(chan *tapApi.OutputChannelItem)
|
||||||
|
go FilterItems(outputItemsChannel, filteredOutputItemsChannel)
|
||||||
|
go api.StartReadingEntries(filteredOutputItemsChannel, nil, ExtensionsMap)
|
||||||
|
|
||||||
|
return outputItemsChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
func FilterItems(inChannel <-chan *tapApi.OutputChannelItem, outChannel chan *tapApi.OutputChannelItem) {
|
||||||
|
for message := range inChannel {
|
||||||
|
if message.ConnectionInfo.IsOutgoing && api.CheckIsServiceIP(message.ConnectionInfo.ServerIP) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
outChannel <- message
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/up9inc/mizu/agent/pkg/api"
|
||||||
"github.com/up9inc/mizu/agent/pkg/config"
|
"github.com/up9inc/mizu/agent/pkg/config"
|
||||||
"github.com/up9inc/mizu/agent/pkg/models"
|
"github.com/up9inc/mizu/agent/pkg/models"
|
||||||
"github.com/up9inc/mizu/agent/pkg/providers"
|
"github.com/up9inc/mizu/agent/pkg/providers"
|
||||||
@@ -36,7 +37,7 @@ func PostTapConfig(c *gin.Context) {
|
|||||||
tappedPods.Set([]*shared.PodInfo{})
|
tappedPods.Set([]*shared.PodInfo{})
|
||||||
tappers.ResetStatus()
|
tappers.ResetStatus()
|
||||||
|
|
||||||
broadcastTappedPodsStatus()
|
api.BroadcastTappedPodsStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
var tappedNamespaces []string
|
var tappedNamespaces []string
|
||||||
@@ -56,7 +57,7 @@ func PostTapConfig(c *gin.Context) {
|
|||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
if _, err := startMizuTapperSyncer(ctx, kubernetesProvider, tappedNamespaces, *podRegex, []string{}, tapApi.TrafficFilteringOptions{}, false); err != nil {
|
if _, err := startMizuTapperSyncer(ctx, kubernetesProvider, tappedNamespaces, *podRegex, []string{}, tapApi.TrafficFilteringOptions{}, false, false); err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, err)
|
c.JSON(http.StatusInternalServerError, err)
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
@@ -99,7 +100,7 @@ func GetTapConfig(c *gin.Context) {
|
|||||||
c.JSON(http.StatusOK, tapConfigToReturn)
|
c.JSON(http.StatusOK, tapConfigToReturn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startMizuTapperSyncer(ctx context.Context, provider *kubernetes.Provider, targetNamespaces []string, podFilterRegex regexp.Regexp, ignoredUserAgents []string, mizuApiFilteringOptions tapApi.TrafficFilteringOptions, serviceMesh bool) (*kubernetes.MizuTapperSyncer, error) {
|
func startMizuTapperSyncer(ctx context.Context, provider *kubernetes.Provider, targetNamespaces []string, podFilterRegex regexp.Regexp, ignoredUserAgents []string, mizuApiFilteringOptions tapApi.TrafficFilteringOptions, serviceMesh bool, tls bool) (*kubernetes.MizuTapperSyncer, error) {
|
||||||
tapperSyncer, err := kubernetes.CreateAndStartMizuTapperSyncer(ctx, provider, kubernetes.TapperSyncerConfig{
|
tapperSyncer, err := kubernetes.CreateAndStartMizuTapperSyncer(ctx, provider, kubernetes.TapperSyncerConfig{
|
||||||
TargetNamespaces: targetNamespaces,
|
TargetNamespaces: targetNamespaces,
|
||||||
PodFilterRegex: podFilterRegex,
|
PodFilterRegex: podFilterRegex,
|
||||||
@@ -112,6 +113,7 @@ func startMizuTapperSyncer(ctx context.Context, provider *kubernetes.Provider, t
|
|||||||
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
||||||
MizuServiceAccountExists: true, //assume service account exists since install mode will not function without it anyway
|
MizuServiceAccountExists: true, //assume service account exists since install mode will not function without it anyway
|
||||||
ServiceMesh: serviceMesh,
|
ServiceMesh: serviceMesh,
|
||||||
|
Tls: tls,
|
||||||
}, time.Now())
|
}, time.Now())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -135,7 +137,7 @@ func startMizuTapperSyncer(ctx context.Context, provider *kubernetes.Provider, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
tappedPods.Set(kubernetes.GetPodInfosForPods(tapperSyncer.CurrentlyTappedPods))
|
tappedPods.Set(kubernetes.GetPodInfosForPods(tapperSyncer.CurrentlyTappedPods))
|
||||||
broadcastTappedPodsStatus()
|
api.BroadcastTappedPodsStatus()
|
||||||
case tapperStatus, ok := <-tapperSyncer.TapperStatusChangedOut:
|
case tapperStatus, ok := <-tapperSyncer.TapperStatusChangedOut:
|
||||||
if !ok {
|
if !ok {
|
||||||
logger.Log.Debug("mizuTapperSyncer tapper status changed channel closed, ending listener loop")
|
logger.Log.Debug("mizuTapperSyncer tapper status changed channel closed, ending listener loop")
|
||||||
@@ -143,7 +145,7 @@ func startMizuTapperSyncer(ctx context.Context, provider *kubernetes.Provider, t
|
|||||||
}
|
}
|
||||||
|
|
||||||
tappers.SetStatus(&tapperStatus)
|
tappers.SetStatus(&tapperStatus)
|
||||||
broadcastTappedPodsStatus()
|
api.BroadcastTappedPodsStatus()
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
logger.Log.Debug("mizuTapperSyncer event listener loop exiting due to context done")
|
logger.Log.Debug("mizuTapperSyncer event listener loop exiting due to context done")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import (
|
|||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/up9inc/mizu/shared"
|
|
||||||
tapApi "github.com/up9inc/mizu/tap/api"
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -59,9 +58,7 @@ type ServiceMapControllerSuite struct {
|
|||||||
|
|
||||||
func (s *ServiceMapControllerSuite) SetupTest() {
|
func (s *ServiceMapControllerSuite) SetupTest() {
|
||||||
s.c = NewServiceMapController()
|
s.c = NewServiceMapController()
|
||||||
s.c.service.SetConfig(&shared.MizuAgentConfig{
|
s.c.service.Enable()
|
||||||
ServiceMap: true,
|
|
||||||
})
|
|
||||||
s.c.service.NewTCPEntry(TCPEntryA, TCPEntryB, ProtocolHttp)
|
s.c.service.NewTCPEntry(TCPEntryA, TCPEntryB, ProtocolHttp)
|
||||||
|
|
||||||
s.w = httptest.NewRecorder()
|
s.w = httptest.NewRecorder()
|
||||||
@@ -102,13 +99,13 @@ func (s *ServiceMapControllerSuite) TestGet() {
|
|||||||
// response nodes
|
// response nodes
|
||||||
aNode := servicemap.ServiceMapNode{
|
aNode := servicemap.ServiceMapNode{
|
||||||
Id: 1,
|
Id: 1,
|
||||||
Name: TCPEntryA.IP,
|
Name: TCPEntryA.Name,
|
||||||
Entry: TCPEntryA,
|
Entry: TCPEntryA,
|
||||||
Count: 1,
|
Count: 1,
|
||||||
}
|
}
|
||||||
bNode := servicemap.ServiceMapNode{
|
bNode := servicemap.ServiceMapNode{
|
||||||
Id: 2,
|
Id: 2,
|
||||||
Name: TCPEntryB.IP,
|
Name: TCPEntryB.Name,
|
||||||
Entry: TCPEntryB,
|
Entry: TCPEntryB,
|
||||||
Count: 1,
|
Count: 1,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -39,18 +38,7 @@ func PostTappedPods(c *gin.Context) {
|
|||||||
|
|
||||||
logger.Log.Infof("[Status] POST request: %d tapped pods", len(requestTappedPods))
|
logger.Log.Infof("[Status] POST request: %d tapped pods", len(requestTappedPods))
|
||||||
tappedPods.Set(requestTappedPods)
|
tappedPods.Set(requestTappedPods)
|
||||||
broadcastTappedPodsStatus()
|
api.BroadcastTappedPodsStatus()
|
||||||
}
|
|
||||||
|
|
||||||
func broadcastTappedPodsStatus() {
|
|
||||||
tappedPodsStatus := tappedPods.GetTappedPodsStatus()
|
|
||||||
|
|
||||||
message := shared.CreateWebSocketStatusMessage(tappedPodsStatus)
|
|
||||||
if jsonBytes, err := json.Marshal(message); err != nil {
|
|
||||||
logger.Log.Errorf("Could not Marshal message %v", err)
|
|
||||||
} else {
|
|
||||||
api.BroadcastToBrowserClients(jsonBytes)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostTapperStatus(c *gin.Context) {
|
func PostTapperStatus(c *gin.Context) {
|
||||||
@@ -67,7 +55,7 @@ func PostTapperStatus(c *gin.Context) {
|
|||||||
|
|
||||||
logger.Log.Infof("[Status] POST request, tapper status: %v", tapperStatus)
|
logger.Log.Infof("[Status] POST request, tapper status: %v", tapperStatus)
|
||||||
tappers.SetStatus(tapperStatus)
|
tappers.SetStatus(tapperStatus)
|
||||||
broadcastTappedPodsStatus()
|
api.BroadcastTappedPodsStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetConnectedTappersCount(c *gin.Context) {
|
func GetConnectedTappersCount(c *gin.Context) {
|
||||||
|
|||||||
@@ -4,13 +4,14 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/elastic/go-elasticsearch/v7"
|
"github.com/elastic/go-elasticsearch/v7"
|
||||||
"github.com/up9inc/mizu/shared"
|
"github.com/up9inc/mizu/shared"
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
"github.com/up9inc/mizu/tap/api"
|
"github.com/up9inc/mizu/tap/api"
|
||||||
"net/http"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type client struct {
|
type client struct {
|
||||||
@@ -31,6 +32,9 @@ func GetInstance() *client {
|
|||||||
|
|
||||||
func (client *client) Configure(config shared.ElasticConfig) {
|
func (client *client) Configure(config shared.ElasticConfig) {
|
||||||
if config.Url == "" || config.User == "" || config.Password == "" {
|
if config.Url == "" || config.User == "" || config.Password == "" {
|
||||||
|
if client.es != nil {
|
||||||
|
client.es = nil
|
||||||
|
}
|
||||||
logger.Log.Infof("No elastic configuration was supplied, elastic exporter disabled")
|
logger.Log.Infof("No elastic configuration was supplied, elastic exporter disabled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -46,13 +50,13 @@ func (client *client) Configure(config shared.ElasticConfig) {
|
|||||||
|
|
||||||
es, err := elasticsearch.NewClient(cfg)
|
es, err := elasticsearch.NewClient(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Fatalf("Failed to initialize elastic client %v", err)
|
logger.Log.Errorf("Failed to initialize elastic client %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have the client instance return a response
|
// Have the client instance return a response
|
||||||
res, err := es.Info()
|
res, err := es.Info()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Fatalf("Elastic client.Info() ERROR: %v", err)
|
logger.Log.Errorf("Elastic client.Info() ERROR: %v", err)
|
||||||
} else {
|
} else {
|
||||||
client.es = es
|
client.es = es
|
||||||
client.index = "mizu_traffic_http_" + time.Now().Format("2006_01_02_15_04")
|
client.index = "mizu_traffic_http_" + time.Now().Format("2006_01_02_15_04")
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ func CORSMiddleware() gin.HandlerFunc {
|
|||||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, x-session-token")
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With, x-session-token")
|
||||||
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||||
|
|
||||||
if c.Request.Method == "OPTIONS" {
|
if c.Request.Method == "OPTIONS" {
|
||||||
c.AbortWithStatus(204)
|
c.AbortWithStatus(204)
|
||||||
|
|||||||
@@ -42,6 +42,11 @@ type WebSocketEntryMessage struct {
|
|||||||
Data *tapApi.BaseEntry `json:"data,omitempty"`
|
Data *tapApi.BaseEntry `json:"data,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WebSocketFullEntryMessage struct {
|
||||||
|
*shared.WebSocketMessageMetadata
|
||||||
|
Data *tapApi.Entry `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type WebSocketTappedEntryMessage struct {
|
type WebSocketTappedEntryMessage struct {
|
||||||
*shared.WebSocketMessageMetadata
|
*shared.WebSocketMessageMetadata
|
||||||
Data *tapApi.OutputChannelItem
|
Data *tapApi.OutputChannelItem
|
||||||
@@ -88,6 +93,16 @@ func CreateBaseEntryWebSocketMessage(base *tapApi.BaseEntry) ([]byte, error) {
|
|||||||
return json.Marshal(message)
|
return json.Marshal(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateFullEntryWebSocketMessage(entry *tapApi.Entry) ([]byte, error) {
|
||||||
|
message := &WebSocketFullEntryMessage{
|
||||||
|
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
|
||||||
|
MessageType: shared.WebSocketMessageTypeFullEntry,
|
||||||
|
},
|
||||||
|
Data: entry,
|
||||||
|
}
|
||||||
|
return json.Marshal(message)
|
||||||
|
}
|
||||||
|
|
||||||
func CreateWebsocketTappedEntryMessage(base *tapApi.OutputChannelItem) ([]byte, error) {
|
func CreateWebsocketTappedEntryMessage(base *tapApi.OutputChannelItem) ([]byte, error) {
|
||||||
message := &WebSocketTappedEntryMessage{
|
message := &WebSocketTappedEntryMessage{
|
||||||
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
|
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ type Counter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Counter) addEntry(ts float64, rt float64, succ bool, dur float64) {
|
func (c *Counter) addEntry(ts float64, rt float64, succ bool, dur float64) {
|
||||||
|
if dur < 0 {
|
||||||
|
panic("Duration cannot be negative")
|
||||||
|
}
|
||||||
|
|
||||||
c.Entries += 1
|
c.Entries += 1
|
||||||
c.SumRT += rt
|
c.SumRT += rt
|
||||||
c.SumDuration += dur
|
c.SumDuration += dur
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -21,20 +22,33 @@ func getFiles(baseDir string) (result []string, err error) {
|
|||||||
result = make([]string, 0)
|
result = make([]string, 0)
|
||||||
logger.Log.Infof("Reading files from tree: %s", baseDir)
|
logger.Log.Infof("Reading files from tree: %s", baseDir)
|
||||||
|
|
||||||
|
inputs := []string{baseDir}
|
||||||
|
|
||||||
// https://yourbasic.org/golang/list-files-in-directory/
|
// https://yourbasic.org/golang/list-files-in-directory/
|
||||||
err = filepath.Walk(baseDir,
|
visitor := func(path string, info os.FileInfo, err error) error {
|
||||||
func(path string, info os.FileInfo, err error) error {
|
if err != nil {
|
||||||
if err != nil {
|
return err
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ext := strings.ToLower(filepath.Ext(path))
|
|
||||||
if !info.IsDir() && (ext == ".har" || ext == ".ldjson") {
|
|
||||||
result = append(result, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if info.Mode()&os.ModeSymlink != 0 {
|
||||||
|
path, _ = os.Readlink(path)
|
||||||
|
inputs = append(inputs, path)
|
||||||
return nil
|
return nil
|
||||||
})
|
}
|
||||||
|
|
||||||
|
ext := strings.ToLower(filepath.Ext(path))
|
||||||
|
if !info.IsDir() && (ext == ".har" || ext == ".ldjson") {
|
||||||
|
result = append(result, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for len(inputs) > 0 {
|
||||||
|
path := inputs[0]
|
||||||
|
inputs = inputs[1:]
|
||||||
|
err = filepath.Walk(path, visitor)
|
||||||
|
}
|
||||||
|
|
||||||
sort.SliceStable(result, func(i, j int) bool {
|
sort.SliceStable(result, func(i, j int) bool {
|
||||||
return fileSize(result[i]) < fileSize(result[j])
|
return fileSize(result[i]) < fileSize(result[j])
|
||||||
@@ -126,7 +140,12 @@ func feedEntry(entry *har.Entry, source string, isSync bool, file string) {
|
|||||||
logger.Log.Debugf("Interesting: %s", entry.Request.URL)
|
logger.Log.Debugf("Interesting: %s", entry.Request.URL)
|
||||||
}
|
}
|
||||||
|
|
||||||
ews := EntryWithSource{Entry: *entry, Source: source}
|
u, err := url.Parse(entry.Request.URL)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ews := EntryWithSource{Entry: *entry, Source: source, Destination: u.Host, Id: uint(0)}
|
||||||
if isSync {
|
if isSync {
|
||||||
GetOasGeneratorInstance().entriesChan <- ews // blocking variant, right?
|
GetOasGeneratorInstance().entriesChan <- ews // blocking variant, right?
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -33,10 +33,23 @@ func (g *oasGenerator) Start() {
|
|||||||
g.entriesChan = make(chan EntryWithSource, 100) // buffer up to 100 entries for OAS processing
|
g.entriesChan = make(chan EntryWithSource, 100) // buffer up to 100 entries for OAS processing
|
||||||
g.ServiceSpecs = &sync.Map{}
|
g.ServiceSpecs = &sync.Map{}
|
||||||
g.started = true
|
g.started = true
|
||||||
go instance.runGeneretor()
|
go instance.runGenerator()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *oasGenerator) runGeneretor() {
|
func (g *oasGenerator) Stop() {
|
||||||
|
if !g.started {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.cancel()
|
||||||
|
g.Reset()
|
||||||
|
g.started = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *oasGenerator) IsStarted() bool {
|
||||||
|
return g.started
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *oasGenerator) runGenerator() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-g.ctx.Done():
|
case <-g.ctx.Done():
|
||||||
@@ -54,11 +67,11 @@ func (g *oasGenerator) runGeneretor() {
|
|||||||
logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err)
|
logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
val, found := g.ServiceSpecs.Load(u.Host)
|
val, found := g.ServiceSpecs.Load(entryWithSource.Destination)
|
||||||
var gen *SpecGen
|
var gen *SpecGen
|
||||||
if !found {
|
if !found {
|
||||||
gen = NewGen(u.Scheme + "://" + u.Host)
|
gen = NewGen(u.Scheme + "://" + entryWithSource.Destination)
|
||||||
g.ServiceSpecs.Store(u.Host, gen)
|
g.ServiceSpecs.Store(entryWithSource.Destination, gen)
|
||||||
} else {
|
} else {
|
||||||
gen = val.(*SpecGen)
|
gen = val.(*SpecGen)
|
||||||
}
|
}
|
||||||
@@ -105,8 +118,10 @@ func newOasGenerator() *oasGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type EntryWithSource struct {
|
type EntryWithSource struct {
|
||||||
Source string
|
Source string
|
||||||
Entry har.Entry
|
Destination string
|
||||||
|
Entry har.Entry
|
||||||
|
Id uint
|
||||||
}
|
}
|
||||||
|
|
||||||
type oasGenerator struct {
|
type oasGenerator struct {
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
const LastSeenTS = "x-last-seen-ts"
|
const LastSeenTS = "x-last-seen-ts"
|
||||||
const CountersTotal = "x-counters-total"
|
const CountersTotal = "x-counters-total"
|
||||||
const CountersPerSource = "x-counters-per-source"
|
const CountersPerSource = "x-counters-per-source"
|
||||||
|
const SampleId = "x-sample-entry"
|
||||||
|
|
||||||
type reqResp struct { // hello, generics in Go
|
type reqResp struct { // hello, generics in Go
|
||||||
Req *har.Request
|
Req *har.Request
|
||||||
@@ -187,7 +188,7 @@ func (g *SpecGen) handlePathObj(entryWithSource *EntryWithSource) (string, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
if entry.Request.Method == "OPTIONS" {
|
if entry.Request.Method == "OPTIONS" {
|
||||||
logger.Log.Debugf("Dropped traffic entry due to its method: %s", urlParsed.Path)
|
logger.Log.Debugf("Dropped traffic entry due to its method: %s %s", entry.Request.Method, urlParsed.Path)
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +307,7 @@ func handleCounters(opObj *openapi.Operation, success bool, entryWithSource *Ent
|
|||||||
rt := float64(entryWithSource.Entry.Time) / 1000
|
rt := float64(entryWithSource.Entry.Time) / 1000
|
||||||
|
|
||||||
dur := 0.0
|
dur := 0.0
|
||||||
if prevTs != 0 {
|
if prevTs != 0 && ts >= prevTs {
|
||||||
dur = ts - prevTs
|
dur = ts - prevTs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,19 +329,39 @@ func handleCounters(opObj *openapi.Operation, success bool, entryWithSource *Ent
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = opObj.Extensions.SetExtension(SampleId, entryWithSource.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRequest(req *har.Request, opObj *openapi.Operation, isSuccess bool) error {
|
func handleRequest(req *har.Request, opObj *openapi.Operation, isSuccess bool) error {
|
||||||
// TODO: we don't handle the situation when header/qstr param can be defined on pathObj level. Also the path param defined on opObj
|
// TODO: we don't handle the situation when header/qstr param can be defined on pathObj level. Also the path param defined on opObj
|
||||||
|
urlParsed, err := url.Parse(req.URL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
qs := make([]har.NVP, 0)
|
||||||
|
for name, vals := range urlParsed.Query() {
|
||||||
|
for _, val := range vals {
|
||||||
|
qs = append(qs, har.NVP{Name: name, Value: val})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(qs) != len(req.QueryString) {
|
||||||
|
logger.Log.Warningf("QStr params in HAR do not match URL: %s", req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
qstrGW := nvParams{
|
qstrGW := nvParams{
|
||||||
In: openapi.InQuery,
|
In: openapi.InQuery,
|
||||||
Pairs: req.QueryString,
|
Pairs: qs,
|
||||||
IsIgnored: func(name string) bool { return false },
|
IsIgnored: func(name string) bool { return false },
|
||||||
GeneralizeName: func(name string) string { return name },
|
GeneralizeName: func(name string) string { return name },
|
||||||
}
|
}
|
||||||
handleNameVals(qstrGW, &opObj.Parameters)
|
handleNameVals(qstrGW, &opObj.Parameters, false)
|
||||||
|
|
||||||
hdrGW := nvParams{
|
hdrGW := nvParams{
|
||||||
In: openapi.InHeader,
|
In: openapi.InHeader,
|
||||||
@@ -348,7 +369,7 @@ func handleRequest(req *har.Request, opObj *openapi.Operation, isSuccess bool) e
|
|||||||
IsIgnored: isHeaderIgnored,
|
IsIgnored: isHeaderIgnored,
|
||||||
GeneralizeName: strings.ToLower,
|
GeneralizeName: strings.ToLower,
|
||||||
}
|
}
|
||||||
handleNameVals(hdrGW, &opObj.Parameters)
|
handleNameVals(hdrGW, &opObj.Parameters, true)
|
||||||
|
|
||||||
if isSuccess {
|
if isSuccess {
|
||||||
reqBody, err := getRequestBody(req, opObj)
|
reqBody, err := getRequestBody(req, opObj)
|
||||||
|
|||||||
@@ -41,14 +41,31 @@ func outputSpec(label string, spec *openapi.OpenAPI, t *testing.T) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEntries(t *testing.T) {
|
func TestEntries(t *testing.T) {
|
||||||
logger.InitLoggerStderrOnly(logging.INFO)
|
logger.InitLoggerStd(logging.INFO)
|
||||||
files, err := getFiles("./test_artifacts/")
|
files, err := getFiles("./test_artifacts/")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(err)
|
t.Log(err)
|
||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
GetOasGeneratorInstance().Start()
|
GetOasGeneratorInstance().Start()
|
||||||
loadStartingOAS()
|
loadStartingOAS("test_artifacts/catalogue.json", "catalogue")
|
||||||
|
loadStartingOAS("test_artifacts/trcc.json", "trcc-api-service")
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
GetOasGeneratorInstance().ServiceSpecs.Range(func(key, val interface{}) bool {
|
||||||
|
svc := key.(string)
|
||||||
|
t.Logf("Getting spec for %s", svc)
|
||||||
|
gen := val.(*SpecGen)
|
||||||
|
_, err := gen.GetSpec()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
cnt, err := feedEntries(files, true)
|
cnt, err := feedEntries(files, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -154,6 +171,13 @@ func TestFileSingle(t *testing.T) {
|
|||||||
t.FailNow()
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if os.Getenv("MIZU_OAS_WRITE_FILES") != "" {
|
||||||
|
err = ioutil.WriteFile(file+".spec.json", []byte(specText), 0644)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(diff) > 0 {
|
if len(diff) > 0 {
|
||||||
t.Errorf("Generated spec does not match expected:\n%s", diff.String())
|
t.Errorf("Generated spec does not match expected:\n%s", diff.String())
|
||||||
}
|
}
|
||||||
@@ -175,8 +199,7 @@ func waitQueueProcessed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadStartingOAS() {
|
func loadStartingOAS(file string, label string) {
|
||||||
file := "test_artifacts/catalogue.json"
|
|
||||||
fd, err := os.Open(file)
|
fd, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -195,10 +218,10 @@ func loadStartingOAS() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gen := NewGen("catalogue")
|
gen := NewGen(label)
|
||||||
gen.StartFromSpec(doc)
|
gen.StartFromSpec(doc)
|
||||||
|
|
||||||
GetOasGeneratorInstance().ServiceSpecs.Store("catalogue", gen)
|
GetOasGeneratorInstance().ServiceSpecs.Store(label, gen)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEntriesNegative(t *testing.T) {
|
func TestEntriesNegative(t *testing.T) {
|
||||||
|
|||||||
@@ -538,6 +538,252 @@
|
|||||||
"wait": -1,
|
"wait": -1,
|
||||||
"receive": 1
|
"receive": 1
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000000+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-fine/234324",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000001+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-sfdlasdfkadf87sd93284q24r/1",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000002+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-adslkfasdf89sa7dfasddafa8a98sd7kansdf/static",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000003+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-4jk5l2345h2452l4352435jlk45",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000004+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-84395h2j4k35hj243j5h2kl34h54k",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"startedDateTime": "2019-09-06T06:16:22.000002+00:00",
|
||||||
|
"time": 1,
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"url": "https://httpbin.org/param-patterns/prefix-gibberish-afterwards/23421",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"queryString": [],
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": -1,
|
||||||
|
"postData": {
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"response": {
|
||||||
|
"status": 200,
|
||||||
|
"statusText": "OK",
|
||||||
|
"httpVersion": "",
|
||||||
|
"cookies": [],
|
||||||
|
"headers": [
|
||||||
|
],
|
||||||
|
"content": {
|
||||||
|
"size": 0,
|
||||||
|
"mimeType": "",
|
||||||
|
"text": ""
|
||||||
|
},
|
||||||
|
"redirectURL": "",
|
||||||
|
"headersSize": -1,
|
||||||
|
"bodySize": 0
|
||||||
|
},
|
||||||
|
"cache": {},
|
||||||
|
"timings": {
|
||||||
|
"send": -1,
|
||||||
|
"wait": -1,
|
||||||
|
"receive": 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"openapi": "3.1.0",
|
"openapi": "3.1.0",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "https://httpbin.org",
|
"title": "https://httpbin.org",
|
||||||
"description": "Mizu observed 13 entries (0 failed), at 0.154 hits/s, average response time is 0.251 seconds",
|
"description": "Mizu observed 19 entries (0 failed), at 0.10 hits/s, average response time is 0.17 seconds",
|
||||||
"version": "1.0"
|
"version": "1.0"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
"/appears-once": {
|
"/appears-once": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "/appears-once",
|
"summary": "/appears-once",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.630 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.63 seconds",
|
||||||
"operationId": "8dfc5a75-5f9b-4b57-ad88-77154a016201",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -30,28 +30,29 @@
|
|||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750580.0471218,
|
"firstSeen": 1567750580.04,
|
||||||
"lastSeen": 1567750580.0471218,
|
"lastSeen": 1567750580.04,
|
||||||
"sumRT": 0.63,
|
"sumRT": 0.63,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750580.0471218,
|
|
||||||
"x-counters-total": {
|
"x-counters-total": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750580.0471218,
|
"firstSeen": 1567750580.04,
|
||||||
"lastSeen": 1567750580.0471218,
|
"lastSeen": 1567750580.04,
|
||||||
"sumRT": 0.63,
|
"sumRT": 0.63,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
},
|
||||||
|
"x-last-seen-ts": 1567750580.04,
|
||||||
|
"x-sample-entry": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/appears-twice": {
|
"/appears-twice": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "/appears-twice",
|
"summary": "/appears-twice",
|
||||||
"description": "Mizu observed 2 entries (0 failed), at 0.500 hits/s, average response time is 0.630 seconds",
|
"description": "Mizu observed 2 entries (0 failed), at 0.50 hits/s, average response time is 0.63 seconds",
|
||||||
"operationId": "844ae464-fcee-4bd7-97cf-aaa096196c02",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -66,28 +67,29 @@
|
|||||||
"": {
|
"": {
|
||||||
"entries": 2,
|
"entries": 2,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750580.7471218,
|
"firstSeen": 1567750580.74,
|
||||||
"lastSeen": 1567750581.7471218,
|
"lastSeen": 1567750581.74,
|
||||||
"sumRT": 1.26,
|
"sumRT": 1.26,
|
||||||
"sumDuration": 1
|
"sumDuration": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750581.7471218,
|
|
||||||
"x-counters-total": {
|
"x-counters-total": {
|
||||||
"entries": 2,
|
"entries": 2,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750580.7471218,
|
"firstSeen": 1567750580.74,
|
||||||
"lastSeen": 1567750581.7471218,
|
"lastSeen": 1567750581.74,
|
||||||
"sumRT": 1.26,
|
"sumRT": 1.26,
|
||||||
"sumDuration": 1
|
"sumDuration": 1
|
||||||
}
|
},
|
||||||
|
"x-last-seen-ts": 1567750581.74,
|
||||||
|
"x-sample-entry": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/body-optional": {
|
"/body-optional": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "/body-optional",
|
"summary": "/body-optional",
|
||||||
"description": "Mizu observed 3 entries (0 failed), at 0.000 hits/s, average response time is 0.001 seconds",
|
"description": "Mizu observed 3 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
"operationId": "6e78e253-1f15-4ecd-9147-ba407c6fbeac",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -96,25 +98,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750581.757122,
|
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 3,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750581.7471218,
|
|
||||||
"lastSeen": 1567750581.757122,
|
|
||||||
"sumRT": 0.003,
|
|
||||||
"sumDuration": 0
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 3,
|
"entries": 3,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750581.7471218,
|
"firstSeen": 1567750581.74,
|
||||||
"lastSeen": 1567750581.757122,
|
"lastSeen": 1567750581.75,
|
||||||
"sumRT": 0.003,
|
"sumRT": 0.00,
|
||||||
"sumDuration": 0
|
"sumDuration": 0.01
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 3,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750581.74,
|
||||||
|
"lastSeen": 1567750581.75,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0.01
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750581.75,
|
||||||
|
"x-sample-entry": 0,
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Generic request body",
|
"description": "Generic request body",
|
||||||
"content": {
|
"content": {
|
||||||
@@ -128,8 +131,8 @@
|
|||||||
"/body-required": {
|
"/body-required": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "/body-required",
|
"summary": "/body-required",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.001 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
"operationId": "1eefebc8-28c0-43d8-877f-4c5f67ff479d",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -138,25 +141,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750581.757122,
|
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 1,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750581.757122,
|
|
||||||
"lastSeen": 1567750581.757122,
|
|
||||||
"sumRT": 0.001,
|
|
||||||
"sumDuration": 0
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750581.757122,
|
"firstSeen": 1567750581.75,
|
||||||
"lastSeen": 1567750581.757122,
|
"lastSeen": 1567750581.75,
|
||||||
"sumRT": 0.001,
|
"sumRT": 0.00,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750581.75,
|
||||||
|
"lastSeen": 1567750581.75,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750581.75,
|
||||||
|
"x-sample-entry": 0,
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Generic request body",
|
"description": "Generic request body",
|
||||||
"content": {
|
"content": {
|
||||||
@@ -171,8 +175,8 @@
|
|||||||
"/form-multipart": {
|
"/form-multipart": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "/form-multipart",
|
"summary": "/form-multipart",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.001 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
"operationId": "fc1eb6a3-3d55-4b4a-bfd0-c2ae85d590d5",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -187,21 +191,22 @@
|
|||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750582.7471218,
|
"firstSeen": 1567750582.74,
|
||||||
"lastSeen": 1567750582.7471218,
|
"lastSeen": 1567750582.74,
|
||||||
"sumRT": 0.001,
|
"sumRT": 0.00,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750582.7471218,
|
|
||||||
"x-counters-total": {
|
"x-counters-total": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750582.7471218,
|
"firstSeen": 1567750582.74,
|
||||||
"lastSeen": 1567750582.7471218,
|
"lastSeen": 1567750582.74,
|
||||||
"sumRT": 0.001,
|
"sumRT": 0.00,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
},
|
},
|
||||||
|
"x-last-seen-ts": 1567750582.74,
|
||||||
|
"x-sample-entry": 0,
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Generic request body",
|
"description": "Generic request body",
|
||||||
"content": {
|
"content": {
|
||||||
@@ -238,8 +243,8 @@
|
|||||||
"/form-urlencoded": {
|
"/form-urlencoded": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "/form-urlencoded",
|
"summary": "/form-urlencoded",
|
||||||
"description": "Mizu observed 2 entries (0 failed), at 0.500 hits/s, average response time is 0.001 seconds",
|
"description": "Mizu observed 2 entries (0 failed), at 0.50 hits/s, average response time is 0.00 seconds",
|
||||||
"operationId": "b416c98b-4ba8-4739-bd2a-6c3e31478bc9",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -248,25 +253,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 2,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750580.7471218,
|
|
||||||
"lastSeen": 1567750581.7471218,
|
|
||||||
"sumRT": 0.002,
|
|
||||||
"sumDuration": 1
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 2,
|
"entries": 2,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750580.7471218,
|
"firstSeen": 1567750580.74,
|
||||||
"lastSeen": 1567750581.7471218,
|
"lastSeen": 1567750581.74,
|
||||||
"sumRT": 0.002,
|
"sumRT": 0.00,
|
||||||
"sumDuration": 1
|
"sumDuration": 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750581.7471218,
|
"x-counters-total": {
|
||||||
|
"entries": 2,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750580.74,
|
||||||
|
"lastSeen": 1567750581.74,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 1
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750581.74,
|
||||||
|
"x-sample-entry": 0,
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"description": "Generic request body",
|
"description": "Generic request body",
|
||||||
"content": {
|
"content": {
|
||||||
@@ -313,11 +319,347 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/param-patterns/prefix-gibberish-fine/{prefixgibberishfineId}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"param-patterns"
|
||||||
|
],
|
||||||
|
"summary": "/param-patterns/prefix-gibberish-fine/{prefixgibberishfineId}",
|
||||||
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
|
"operationId": "<UUID4>",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful call with status 200",
|
||||||
|
"content": {
|
||||||
|
"": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-per-source": {
|
||||||
|
"": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582,
|
||||||
|
"lastSeen": 1567750582,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582,
|
||||||
|
"lastSeen": 1567750582,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750582,
|
||||||
|
"x-sample-entry": 0
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "prefixgibberishfineId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "234324"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/param-patterns/{parampatternId}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"param-patterns"
|
||||||
|
],
|
||||||
|
"summary": "/param-patterns/{parampatternId}",
|
||||||
|
"description": "Mizu observed 2 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
|
"operationId": "<UUID4>",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful call with status 200",
|
||||||
|
"content": {
|
||||||
|
"": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-per-source": {
|
||||||
|
"": {
|
||||||
|
"entries": 2,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 9.53e-7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 2,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 9.53e-7
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750582.00,
|
||||||
|
"x-sample-entry": 0
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "parampatternId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^prefix-gibberish-.+"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "prefix-gibberish-sfdlasdfkadf87sd93284q24r"
|
||||||
|
},
|
||||||
|
"example #1": {
|
||||||
|
"value": "prefix-gibberish-adslkfasdf89sa7dfasddafa8a98sd7kansdf"
|
||||||
|
},
|
||||||
|
"example #2": {
|
||||||
|
"value": "prefix-gibberish-4jk5l2345h2452l4352435jlk45"
|
||||||
|
},
|
||||||
|
"example #3": {
|
||||||
|
"value": "prefix-gibberish-84395h2j4k35hj243j5h2kl34h54k"
|
||||||
|
},
|
||||||
|
"example #4": {
|
||||||
|
"value": "prefix-gibberish-afterwards"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/param-patterns/{parampatternId}/1": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"param-patterns"
|
||||||
|
],
|
||||||
|
"summary": "/param-patterns/{parampatternId}/1",
|
||||||
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
|
"operationId": "<UUID4>",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful call with status 200",
|
||||||
|
"content": {
|
||||||
|
"": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-per-source": {
|
||||||
|
"": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750582.00,
|
||||||
|
"x-sample-entry": 0
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "parampatternId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^prefix-gibberish-.+"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "prefix-gibberish-sfdlasdfkadf87sd93284q24r"
|
||||||
|
},
|
||||||
|
"example #1": {
|
||||||
|
"value": "prefix-gibberish-adslkfasdf89sa7dfasddafa8a98sd7kansdf"
|
||||||
|
},
|
||||||
|
"example #2": {
|
||||||
|
"value": "prefix-gibberish-4jk5l2345h2452l4352435jlk45"
|
||||||
|
},
|
||||||
|
"example #3": {
|
||||||
|
"value": "prefix-gibberish-84395h2j4k35hj243j5h2kl34h54k"
|
||||||
|
},
|
||||||
|
"example #4": {
|
||||||
|
"value": "prefix-gibberish-afterwards"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/param-patterns/{parampatternId}/static": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"param-patterns"
|
||||||
|
],
|
||||||
|
"summary": "/param-patterns/{parampatternId}/static",
|
||||||
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
|
"operationId": "<UUID4>",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful call with status 200",
|
||||||
|
"content": {
|
||||||
|
"": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-per-source": {
|
||||||
|
"": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750582.00,
|
||||||
|
"x-sample-entry": 0
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "parampatternId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^prefix-gibberish-.+"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "prefix-gibberish-sfdlasdfkadf87sd93284q24r"
|
||||||
|
},
|
||||||
|
"example #1": {
|
||||||
|
"value": "prefix-gibberish-adslkfasdf89sa7dfasddafa8a98sd7kansdf"
|
||||||
|
},
|
||||||
|
"example #2": {
|
||||||
|
"value": "prefix-gibberish-4jk5l2345h2452l4352435jlk45"
|
||||||
|
},
|
||||||
|
"example #3": {
|
||||||
|
"value": "prefix-gibberish-84395h2j4k35hj243j5h2kl34h54k"
|
||||||
|
},
|
||||||
|
"example #4": {
|
||||||
|
"value": "prefix-gibberish-afterwards"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/param-patterns/{parampatternId}/{param1}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"param-patterns"
|
||||||
|
],
|
||||||
|
"summary": "/param-patterns/{parampatternId}/{param1}",
|
||||||
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.00 seconds",
|
||||||
|
"operationId": "<UUID4>",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful call with status 200",
|
||||||
|
"content": {
|
||||||
|
"": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-per-source": {
|
||||||
|
"": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750582.00,
|
||||||
|
"lastSeen": 1567750582.00,
|
||||||
|
"sumRT": 0.00,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750582.00,
|
||||||
|
"x-sample-entry": 0
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "param1",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "23421"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "parampatternId",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "^prefix-gibberish-.+"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"example #0": {
|
||||||
|
"value": "prefix-gibberish-sfdlasdfkadf87sd93284q24r"
|
||||||
|
},
|
||||||
|
"example #1": {
|
||||||
|
"value": "prefix-gibberish-adslkfasdf89sa7dfasddafa8a98sd7kansdf"
|
||||||
|
},
|
||||||
|
"example #2": {
|
||||||
|
"value": "prefix-gibberish-4jk5l2345h2452l4352435jlk45"
|
||||||
|
},
|
||||||
|
"example #3": {
|
||||||
|
"value": "prefix-gibberish-84395h2j4k35hj243j5h2kl34h54k"
|
||||||
|
},
|
||||||
|
"example #4": {
|
||||||
|
"value": "prefix-gibberish-afterwards"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"/{Id}": {
|
"/{Id}": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "/{Id}",
|
"summary": "/{Id}",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.630 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.63 seconds",
|
||||||
"operationId": "d8b4de17-4c0e-401c-891b-36a7cee390bf",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -328,25 +670,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750579.7471218,
|
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 1,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750579.7471218,
|
|
||||||
"lastSeen": 1567750579.7471218,
|
|
||||||
"sumRT": 0.63,
|
|
||||||
"sumDuration": 0
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750579.7471218,
|
"firstSeen": 1567750579.74,
|
||||||
"lastSeen": 1567750579.7471218,
|
"lastSeen": 1567750579.74,
|
||||||
"sumRT": 0.63,
|
"sumRT": 0.63,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750579.74,
|
||||||
|
"lastSeen": 1567750579.74,
|
||||||
|
"sumRT": 0.63,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750579.74,
|
||||||
|
"x-sample-entry": 0
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@@ -359,10 +702,10 @@
|
|||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"example #0": {
|
"example #0": {
|
||||||
"value": "e21f7112-3d3b-4632-9da3-a4af2e0e9166"
|
"value": "<UUID4>"
|
||||||
},
|
},
|
||||||
"example #1": {
|
"example #1": {
|
||||||
"value": "952bea17-3776-11ea-9341-42010a84012a"
|
"value": "<UUID4>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,8 +714,8 @@
|
|||||||
"/{Id}/sub1": {
|
"/{Id}/sub1": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "/{Id}/sub1",
|
"summary": "/{Id}/sub1",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.111 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.11 seconds",
|
||||||
"operationId": "edacc275-1761-4011-af9b-3a3ed7c3d2b8",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -381,25 +724,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 1,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750483.864529,
|
|
||||||
"lastSeen": 1567750483.864529,
|
|
||||||
"sumRT": 0.111,
|
|
||||||
"sumDuration": 0
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750483.864529,
|
"firstSeen": 1567750483.86,
|
||||||
"lastSeen": 1567750483.864529,
|
"lastSeen": 1567750483.86,
|
||||||
"sumRT": 0.111,
|
"sumRT": 0.11,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750483.864529
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750483.86,
|
||||||
|
"lastSeen": 1567750483.86,
|
||||||
|
"sumRT": 0.11,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750483.86,
|
||||||
|
"x-sample-entry": 0
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@@ -412,10 +756,10 @@
|
|||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"example #0": {
|
"example #0": {
|
||||||
"value": "e21f7112-3d3b-4632-9da3-a4af2e0e9166"
|
"value": "<UUID4>"
|
||||||
},
|
},
|
||||||
"example #1": {
|
"example #1": {
|
||||||
"value": "952bea17-3776-11ea-9341-42010a84012a"
|
"value": "<UUID4>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,8 +768,8 @@
|
|||||||
"/{Id}/sub2": {
|
"/{Id}/sub2": {
|
||||||
"get": {
|
"get": {
|
||||||
"summary": "/{Id}/sub2",
|
"summary": "/{Id}/sub2",
|
||||||
"description": "Mizu observed 1 entries (0 failed), at 0.000 hits/s, average response time is 0.630 seconds",
|
"description": "Mizu observed 1 entries (0 failed), at 0.00 hits/s, average response time is 0.63 seconds",
|
||||||
"operationId": "61702da5-e4e7-4d95-8071-a6208f3d19d4",
|
"operationId": "<UUID4>",
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Successful call with status 200",
|
"description": "Successful call with status 200",
|
||||||
@@ -436,25 +780,26 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-last-seen-ts": 1567750578.7471218,
|
|
||||||
"x-counters-total": {
|
|
||||||
"entries": 1,
|
|
||||||
"failures": 0,
|
|
||||||
"firstSeen": 1567750578.7471218,
|
|
||||||
"lastSeen": 1567750578.7471218,
|
|
||||||
"sumRT": 0.63,
|
|
||||||
"sumDuration": 0
|
|
||||||
},
|
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 1,
|
"entries": 1,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750578.7471218,
|
"firstSeen": 1567750578.74,
|
||||||
"lastSeen": 1567750578.7471218,
|
"lastSeen": 1567750578.74,
|
||||||
"sumRT": 0.63,
|
"sumRT": 0.63,
|
||||||
"sumDuration": 0
|
"sumDuration": 0
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"x-counters-total": {
|
||||||
|
"entries": 1,
|
||||||
|
"failures": 0,
|
||||||
|
"firstSeen": 1567750578.74,
|
||||||
|
"lastSeen": 1567750578.74,
|
||||||
|
"sumRT": 0.63,
|
||||||
|
"sumDuration": 0
|
||||||
|
},
|
||||||
|
"x-last-seen-ts": 1567750578.74,
|
||||||
|
"x-sample-entry": 0
|
||||||
},
|
},
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
@@ -467,10 +812,10 @@
|
|||||||
},
|
},
|
||||||
"examples": {
|
"examples": {
|
||||||
"example #0": {
|
"example #0": {
|
||||||
"value": "e21f7112-3d3b-4632-9da3-a4af2e0e9166"
|
"value": "<UUID4>"
|
||||||
},
|
},
|
||||||
"example #1": {
|
"example #1": {
|
||||||
"value": "952bea17-3776-11ea-9341-42010a84012a"
|
"value": "<UUID4>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -479,20 +824,20 @@
|
|||||||
},
|
},
|
||||||
"x-counters-per-source": {
|
"x-counters-per-source": {
|
||||||
"": {
|
"": {
|
||||||
"entries": 13,
|
"entries": 19,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750483.864529,
|
"firstSeen": 1567750483.86,
|
||||||
"lastSeen": 1567750582.7471218,
|
"lastSeen": 1567750582.74,
|
||||||
"sumRT": 3.268,
|
"sumRT": 3.27,
|
||||||
"sumDuration": 2
|
"sumDuration": 2.01
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-counters-total": {
|
"x-counters-total": {
|
||||||
"entries": 13,
|
"entries": 19,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"firstSeen": 1567750483.864529,
|
"firstSeen": 1567750483.86,
|
||||||
"lastSeen": 1567750582.7471218,
|
"lastSeen": 1567750582.74,
|
||||||
"sumRT": 3.268,
|
"sumRT": 3.27,
|
||||||
"sumDuration": 2
|
"sumDuration": 2.01
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
50
agent/pkg/oas/test_artifacts/trcc.json
Normal file
50
agent/pkg/oas/test_artifacts/trcc.json
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"info": {
|
||||||
|
"title": "Preloaded TRCC",
|
||||||
|
"version": "0.1",
|
||||||
|
"description": "Test file for loading pre-existing OAS"
|
||||||
|
},
|
||||||
|
"paths": {
|
||||||
|
"/models/{id}": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": ".+(_|-|\\.).+"
|
||||||
|
},
|
||||||
|
"example": "some-uuid-maybe"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/models/{id}/{id2}": {
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": ".+(_|-|\\.).+"
|
||||||
|
},
|
||||||
|
"example": "some-uuid-maybe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "id2",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"style": "simple",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"pattern": "\\d+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
package oas
|
package oas
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"encoding/json"
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/chanced/openapi"
|
"github.com/chanced/openapi"
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodePath = []string
|
type NodePath = []string
|
||||||
@@ -49,8 +50,8 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node *
|
|||||||
node = n.searchInConstants(pathChunk)
|
node = n.searchInConstants(pathChunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
if node == nil {
|
if node == nil && pathChunk != "" {
|
||||||
node = n.searchInParams(paramObj, chunkIsGibberish)
|
node = n.searchInParams(paramObj, pathChunk, chunkIsGibberish)
|
||||||
}
|
}
|
||||||
|
|
||||||
// still no node found, should create it
|
// still no node found, should create it
|
||||||
@@ -76,6 +77,10 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node *
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Warningf("Failed to add example to a parameter: %s", err)
|
logger.Log.Warningf("Failed to add example to a parameter: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(*exmp) >= 3 && node.pathParam.Schema.Pattern == nil { // is it enough to decide on 2 samples?
|
||||||
|
node.pathParam.Schema.Pattern = getPatternFromExamples(exmp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: eat up trailing slash, in a smart way: node.pathObj!=nil && path[1]==""
|
// TODO: eat up trailing slash, in a smart way: node.pathObj!=nil && path[1]==""
|
||||||
@@ -88,6 +93,57 @@ func (n *Node) getOrSet(path NodePath, existingPathObj *openapi.PathObj) (node *
|
|||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPatternFromExamples(exmp *openapi.Examples) *openapi.Regexp {
|
||||||
|
allInts := true
|
||||||
|
strs := make([]string, 0)
|
||||||
|
for _, example := range *exmp {
|
||||||
|
exampleObj, err := example.ResolveExample(exampleResolver)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var value string
|
||||||
|
err = json.Unmarshal(exampleObj.Value, &value)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Warningf("Failed decoding parameter example into string: %s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
strs = append(strs, value)
|
||||||
|
|
||||||
|
if _, err := strconv.Atoi(value); err != nil {
|
||||||
|
allInts = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if allInts {
|
||||||
|
re := new(openapi.Regexp)
|
||||||
|
re.Regexp = regexp.MustCompile(`\d+`)
|
||||||
|
return re
|
||||||
|
} else {
|
||||||
|
prefix := longestCommonXfixStr(strs, true)
|
||||||
|
suffix := longestCommonXfixStr(strs, false)
|
||||||
|
|
||||||
|
pat := ""
|
||||||
|
separators := "-._/:|*,+" // TODO: we could also cut prefix till the last separator
|
||||||
|
if len(prefix) > 0 && strings.Contains(separators, string(prefix[len(prefix)-1])) {
|
||||||
|
pat = "^" + regexp.QuoteMeta(prefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
pat += ".+"
|
||||||
|
|
||||||
|
if len(suffix) > 0 && strings.Contains(separators, string(suffix[0])) {
|
||||||
|
pat += regexp.QuoteMeta(suffix) + "$"
|
||||||
|
}
|
||||||
|
|
||||||
|
if pat != ".+" {
|
||||||
|
re := new(openapi.Regexp)
|
||||||
|
re.Regexp = regexp.MustCompile(pat)
|
||||||
|
return re
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Node) createParam() *openapi.ParameterObj {
|
func (n *Node) createParam() *openapi.ParameterObj {
|
||||||
name := "param"
|
name := "param"
|
||||||
|
|
||||||
@@ -118,23 +174,30 @@ func (n *Node) createParam() *openapi.ParameterObj {
|
|||||||
return newParam
|
return newParam
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) searchInParams(paramObj *openapi.ParameterObj, chunkIsGibberish bool) *Node {
|
func (n *Node) searchInParams(paramObj *openapi.ParameterObj, chunk string, chunkIsGibberish bool) *Node {
|
||||||
// look among params
|
// look among params
|
||||||
if paramObj != nil || chunkIsGibberish {
|
for _, subnode := range n.children {
|
||||||
for _, subnode := range n.children {
|
if subnode.constant != nil {
|
||||||
if subnode.constant != nil {
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: check the regex pattern of param? for exceptions etc
|
|
||||||
|
|
||||||
if paramObj != nil {
|
|
||||||
// TODO: mergeParam(subnode.pathParam, paramObj)
|
|
||||||
return subnode
|
|
||||||
} else {
|
|
||||||
return subnode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if paramObj != nil {
|
||||||
|
// TODO: mergeParam(subnode.pathParam, paramObj)
|
||||||
|
return subnode
|
||||||
|
} else if subnode.pathParam.Schema.Pattern != nil { // it has defined param pattern, have to respect it
|
||||||
|
// TODO: and not in exceptions
|
||||||
|
if subnode.pathParam.Schema.Pattern.Match([]byte(chunk)) {
|
||||||
|
return subnode
|
||||||
|
} else if chunkIsGibberish {
|
||||||
|
// TODO: what to do if gibberish chunk does not match the pattern and not in exceptions?
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else if chunkIsGibberish {
|
||||||
|
return subnode
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,10 +115,10 @@ type nvParams struct {
|
|||||||
GeneralizeName func(name string) string
|
GeneralizeName func(name string) string
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleNameVals(gw nvParams, params **openapi.ParameterList) {
|
func handleNameVals(gw nvParams, params **openapi.ParameterList, checkIgnore bool) {
|
||||||
visited := map[string]*openapi.ParameterObj{}
|
visited := map[string]*openapi.ParameterObj{}
|
||||||
for _, pair := range gw.Pairs {
|
for _, pair := range gw.Pairs {
|
||||||
if gw.IsIgnored(pair.Name) {
|
if (checkIgnore && gw.IsIgnored(pair.Name)) || pair.Name == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,6 +290,53 @@ func longestCommonXfix(strs [][]string, pre bool) []string { // https://github.c
|
|||||||
return xfix
|
return xfix
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func longestCommonXfixStr(strs []string, pre bool) string { // https://github.com/jpillora/longestcommon
|
||||||
|
//short-circuit empty list
|
||||||
|
if len(strs) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
xfix := strs[0]
|
||||||
|
//short-circuit single-element list
|
||||||
|
if len(strs) == 1 {
|
||||||
|
return xfix
|
||||||
|
}
|
||||||
|
//compare first to rest
|
||||||
|
for _, str := range strs[1:] {
|
||||||
|
xfixl := len(xfix)
|
||||||
|
strl := len(str)
|
||||||
|
//short-circuit empty strings
|
||||||
|
if xfixl == 0 || strl == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
//maximum possible length
|
||||||
|
maxl := xfixl
|
||||||
|
if strl < maxl {
|
||||||
|
maxl = strl
|
||||||
|
}
|
||||||
|
//compare letters
|
||||||
|
if pre {
|
||||||
|
//prefix, iterate left to right
|
||||||
|
for i := 0; i < maxl; i++ {
|
||||||
|
if xfix[i] != str[i] {
|
||||||
|
xfix = xfix[:i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//suffix, iternate right to left
|
||||||
|
for i := 0; i < maxl; i++ {
|
||||||
|
xi := xfixl - i - 1
|
||||||
|
si := strl - i - 1
|
||||||
|
if xfix[xi] != str[si] {
|
||||||
|
xfix = xfix[xi+1:]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return xfix
|
||||||
|
}
|
||||||
|
|
||||||
func getSimilarPrefix(strs []string) string {
|
func getSimilarPrefix(strs []string) string {
|
||||||
chunked := make([][]string, 0)
|
chunked := make([][]string, 0)
|
||||||
for _, item := range strs {
|
for _, item := range strs {
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ type Resolver struct {
|
|||||||
namespace string
|
namespace string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ResolvedObjectInfo struct {
|
||||||
|
FullAddress string
|
||||||
|
Namespace string
|
||||||
|
}
|
||||||
|
|
||||||
func (resolver *Resolver) Start(ctx context.Context) {
|
func (resolver *Resolver) Start(ctx context.Context) {
|
||||||
if !resolver.isStarted {
|
if !resolver.isStarted {
|
||||||
resolver.isStarted = true
|
resolver.isStarted = true
|
||||||
@@ -40,12 +45,12 @@ func (resolver *Resolver) Start(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resolver *Resolver) Resolve(name string) string {
|
func (resolver *Resolver) Resolve(name string) *ResolvedObjectInfo {
|
||||||
resolvedName, isFound := resolver.nameMap.Get(name)
|
resolvedName, isFound := resolver.nameMap.Get(name)
|
||||||
if !isFound {
|
if !isFound {
|
||||||
return ""
|
return nil
|
||||||
}
|
}
|
||||||
return resolvedName.(string)
|
return resolvedName.(*ResolvedObjectInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resolver *Resolver) GetMap() cmap.ConcurrentMap {
|
func (resolver *Resolver) GetMap() cmap.ConcurrentMap {
|
||||||
@@ -71,7 +76,7 @@ func (resolver *Resolver) watchPods(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
if event.Type == watch.Deleted {
|
if event.Type == watch.Deleted {
|
||||||
pod := event.Object.(*corev1.Pod)
|
pod := event.Object.(*corev1.Pod)
|
||||||
resolver.saveResolvedName(pod.Status.PodIP, "", event.Type)
|
resolver.saveResolvedName(pod.Status.PodIP, "", pod.Namespace, event.Type)
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
watcher.Stop()
|
watcher.Stop()
|
||||||
@@ -106,10 +111,10 @@ func (resolver *Resolver) watchEndpoints(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
if subset.Addresses != nil {
|
if subset.Addresses != nil {
|
||||||
for _, address := range subset.Addresses {
|
for _, address := range subset.Addresses {
|
||||||
resolver.saveResolvedName(address.IP, serviceHostname, event.Type)
|
resolver.saveResolvedName(address.IP, serviceHostname, endpoint.Namespace, event.Type)
|
||||||
for _, port := range ports {
|
for _, port := range ports {
|
||||||
ipWithPort := fmt.Sprintf("%s:%d", address.IP, port)
|
ipWithPort := fmt.Sprintf("%s:%d", address.IP, port)
|
||||||
resolver.saveResolvedName(ipWithPort, serviceHostname, event.Type)
|
resolver.saveResolvedName(ipWithPort, serviceHostname, endpoint.Namespace, event.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,19 +144,19 @@ func (resolver *Resolver) watchServices(ctx context.Context) error {
|
|||||||
service := event.Object.(*corev1.Service)
|
service := event.Object.(*corev1.Service)
|
||||||
serviceHostname := fmt.Sprintf("%s.%s", service.Name, service.Namespace)
|
serviceHostname := fmt.Sprintf("%s.%s", service.Name, service.Namespace)
|
||||||
if service.Spec.ClusterIP != "" && service.Spec.ClusterIP != kubClientNullString {
|
if service.Spec.ClusterIP != "" && service.Spec.ClusterIP != kubClientNullString {
|
||||||
resolver.saveResolvedName(service.Spec.ClusterIP, serviceHostname, event.Type)
|
resolver.saveResolvedName(service.Spec.ClusterIP, serviceHostname, service.Namespace, event.Type)
|
||||||
if service.Spec.Ports != nil {
|
if service.Spec.Ports != nil {
|
||||||
for _, port := range service.Spec.Ports {
|
for _, port := range service.Spec.Ports {
|
||||||
if port.Port > 0 {
|
if port.Port > 0 {
|
||||||
resolver.saveResolvedName(fmt.Sprintf("%s:%d", service.Spec.ClusterIP, port.Port), serviceHostname, event.Type)
|
resolver.saveResolvedName(fmt.Sprintf("%s:%d", service.Spec.ClusterIP, port.Port), serviceHostname, service.Namespace, event.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resolver.saveServiceIP(service.Spec.ClusterIP, serviceHostname, event.Type)
|
resolver.saveServiceIP(service.Spec.ClusterIP, serviceHostname, service.Namespace, event.Type)
|
||||||
}
|
}
|
||||||
if service.Status.LoadBalancer.Ingress != nil {
|
if service.Status.LoadBalancer.Ingress != nil {
|
||||||
for _, ingress := range service.Status.LoadBalancer.Ingress {
|
for _, ingress := range service.Status.LoadBalancer.Ingress {
|
||||||
resolver.saveResolvedName(ingress.IP, serviceHostname, event.Type)
|
resolver.saveResolvedName(ingress.IP, serviceHostname, service.Namespace, event.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -161,21 +166,22 @@ func (resolver *Resolver) watchServices(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resolver *Resolver) saveResolvedName(key string, resolved string, eventType watch.EventType) {
|
func (resolver *Resolver) saveResolvedName(key string, resolved string, namespace string, eventType watch.EventType) {
|
||||||
if eventType == watch.Deleted {
|
if eventType == watch.Deleted {
|
||||||
resolver.nameMap.Remove(key)
|
resolver.nameMap.Remove(key)
|
||||||
logger.Log.Infof("setting %s=nil", key)
|
logger.Log.Infof("setting %s=nil", key)
|
||||||
} else {
|
} else {
|
||||||
resolver.nameMap.Set(key, resolved)
|
|
||||||
|
resolver.nameMap.Set(key, &ResolvedObjectInfo{FullAddress: resolved, Namespace: namespace})
|
||||||
logger.Log.Infof("setting %s=%s", key, resolved)
|
logger.Log.Infof("setting %s=%s", key, resolved)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (resolver *Resolver) saveServiceIP(key string, resolved string, eventType watch.EventType) {
|
func (resolver *Resolver) saveServiceIP(key string, resolved string, namespace string, eventType watch.EventType) {
|
||||||
if eventType == watch.Deleted {
|
if eventType == watch.Deleted {
|
||||||
resolver.serviceMap.Remove(key)
|
resolver.serviceMap.Remove(key)
|
||||||
} else {
|
} else {
|
||||||
resolver.serviceMap.Set(key, resolved)
|
resolver.nameMap.Set(key, &ResolvedObjectInfo{FullAddress: resolved, Namespace: namespace})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package servicemap
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/shared"
|
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
tapApi "github.com/up9inc/mizu/tap/api"
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
)
|
)
|
||||||
@@ -26,13 +25,14 @@ func GetInstance() ServiceMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type serviceMap struct {
|
type serviceMap struct {
|
||||||
config *shared.MizuAgentConfig
|
enabled bool
|
||||||
graph *graph
|
graph *graph
|
||||||
entriesProcessed int
|
entriesProcessed int
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceMap interface {
|
type ServiceMap interface {
|
||||||
SetConfig(config *shared.MizuAgentConfig)
|
Enable()
|
||||||
|
Disable()
|
||||||
IsEnabled() bool
|
IsEnabled() bool
|
||||||
NewTCPEntry(source *tapApi.TCP, destination *tapApi.TCP, protocol *tapApi.Protocol)
|
NewTCPEntry(source *tapApi.TCP, destination *tapApi.TCP, protocol *tapApi.Protocol)
|
||||||
GetStatus() ServiceMapStatus
|
GetStatus() ServiceMapStatus
|
||||||
@@ -46,7 +46,7 @@ type ServiceMap interface {
|
|||||||
|
|
||||||
func newServiceMap() *serviceMap {
|
func newServiceMap() *serviceMap {
|
||||||
return &serviceMap{
|
return &serviceMap{
|
||||||
config: nil,
|
enabled: false,
|
||||||
entriesProcessed: 0,
|
entriesProcessed: 0,
|
||||||
graph: newDirectedGraph(),
|
graph: newDirectedGraph(),
|
||||||
}
|
}
|
||||||
@@ -156,15 +156,17 @@ func (s *serviceMap) addEdge(u, v *entryData, p *tapApi.Protocol) {
|
|||||||
s.entriesProcessed++
|
s.entriesProcessed++
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceMap) SetConfig(config *shared.MizuAgentConfig) {
|
func (s *serviceMap) Enable() {
|
||||||
s.config = config
|
s.enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *serviceMap) Disable() {
|
||||||
|
s.Reset()
|
||||||
|
s.enabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceMap) IsEnabled() bool {
|
func (s *serviceMap) IsEnabled() bool {
|
||||||
if s.config != nil && s.config.ServiceMap {
|
return s.enabled
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *serviceMap) NewTCPEntry(src *tapApi.TCP, dst *tapApi.TCP, p *tapApi.Protocol) {
|
func (s *serviceMap) NewTCPEntry(src *tapApi.TCP, dst *tapApi.TCP, p *tapApi.Protocol) {
|
||||||
@@ -172,20 +174,33 @@ func (s *serviceMap) NewTCPEntry(src *tapApi.TCP, dst *tapApi.TCP, p *tapApi.Pro
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
srcEntry := &entryData{
|
var srcEntry *entryData
|
||||||
key: key(src.IP),
|
var dstEntry *entryData
|
||||||
entry: src,
|
|
||||||
}
|
if len(src.Name) == 0 {
|
||||||
if len(srcEntry.entry.Name) == 0 {
|
srcEntry = &entryData{
|
||||||
|
key: key(src.IP),
|
||||||
|
entry: src,
|
||||||
|
}
|
||||||
srcEntry.entry.Name = UnresolvedNodeName
|
srcEntry.entry.Name = UnresolvedNodeName
|
||||||
|
} else {
|
||||||
|
srcEntry = &entryData{
|
||||||
|
key: key(src.Name),
|
||||||
|
entry: src,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dstEntry := &entryData{
|
if len(dst.Name) == 0 {
|
||||||
key: key(dst.IP),
|
dstEntry = &entryData{
|
||||||
entry: dst,
|
key: key(dst.IP),
|
||||||
}
|
entry: dst,
|
||||||
if len(dstEntry.entry.Name) == 0 {
|
}
|
||||||
dstEntry.entry.Name = UnresolvedNodeName
|
dstEntry.entry.Name = UnresolvedNodeName
|
||||||
|
} else {
|
||||||
|
dstEntry = &entryData{
|
||||||
|
key: key(dst.Name),
|
||||||
|
entry: dst,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.addEdge(srcEntry, dstEntry, p)
|
s.addEdge(srcEntry, dstEntry, p)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"github.com/up9inc/mizu/shared"
|
|
||||||
tapApi "github.com/up9inc/mizu/tap/api"
|
tapApi "github.com/up9inc/mizu/tap/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -96,9 +95,7 @@ func (s *ServiceMapDisabledSuite) SetupTest() {
|
|||||||
|
|
||||||
func (s *ServiceMapEnabledSuite) SetupTest() {
|
func (s *ServiceMapEnabledSuite) SetupTest() {
|
||||||
s.instance = GetInstance()
|
s.instance = GetInstance()
|
||||||
s.instance.SetConfig(&shared.MizuAgentConfig{
|
s.instance.Enable()
|
||||||
ServiceMap: true,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ServiceMapDisabledSuite) TestServiceMapInstance() {
|
func (s *ServiceMapDisabledSuite) TestServiceMapInstance() {
|
||||||
@@ -268,9 +265,14 @@ func (s *ServiceMapEnabledSuite) TestServiceMap() {
|
|||||||
assert.LessOrEqual(node.Id, expectedNodeCount)
|
assert.LessOrEqual(node.Id, expectedNodeCount)
|
||||||
|
|
||||||
// entry
|
// entry
|
||||||
// node.Name is the key of the node, key = entry.IP
|
// node.Name is the key of the node, key = entry.Name by default
|
||||||
// entry.Name is the name of the service and could be unresolved
|
// entry.Name is the name of the service and could be unresolved
|
||||||
assert.Equal(node.Name, node.Entry.IP)
|
// when entry.Name is unresolved, key = entry.IP
|
||||||
|
if node.Entry.Name == UnresolvedNodeName {
|
||||||
|
assert.Equal(node.Name, node.Entry.IP)
|
||||||
|
} else {
|
||||||
|
assert.Equal(node.Name, node.Entry.Name)
|
||||||
|
}
|
||||||
assert.Equal(Port, node.Entry.Port)
|
assert.Equal(Port, node.Entry.Port)
|
||||||
assert.Equal(entryName, node.Entry.Name)
|
assert.Equal(entryName, node.Entry.Name)
|
||||||
|
|
||||||
@@ -320,16 +322,24 @@ func (s *ServiceMapEnabledSuite) TestServiceMap() {
|
|||||||
cdEdge := -1
|
cdEdge := -1
|
||||||
acEdge := -1
|
acEdge := -1
|
||||||
var validateEdge = func(edge ServiceMapEdge, sourceEntryName string, destEntryName string, protocolName string, protocolCount int) {
|
var validateEdge = func(edge ServiceMapEdge, sourceEntryName string, destEntryName string, protocolName string, protocolCount int) {
|
||||||
// source
|
// source node
|
||||||
assert.Contains(nodeIds, edge.Source.Id)
|
assert.Contains(nodeIds, edge.Source.Id)
|
||||||
assert.LessOrEqual(edge.Source.Id, expectedNodeCount)
|
assert.LessOrEqual(edge.Source.Id, expectedNodeCount)
|
||||||
assert.Equal(edge.Source.Name, edge.Source.Entry.IP)
|
if edge.Source.Entry.Name == UnresolvedNodeName {
|
||||||
|
assert.Equal(edge.Source.Name, edge.Source.Entry.IP)
|
||||||
|
} else {
|
||||||
|
assert.Equal(edge.Source.Name, edge.Source.Entry.Name)
|
||||||
|
}
|
||||||
assert.Equal(sourceEntryName, edge.Source.Entry.Name)
|
assert.Equal(sourceEntryName, edge.Source.Entry.Name)
|
||||||
|
|
||||||
// destination
|
// destination node
|
||||||
assert.Contains(nodeIds, edge.Destination.Id)
|
assert.Contains(nodeIds, edge.Destination.Id)
|
||||||
assert.LessOrEqual(edge.Destination.Id, expectedNodeCount)
|
assert.LessOrEqual(edge.Destination.Id, expectedNodeCount)
|
||||||
assert.Equal(edge.Destination.Name, edge.Destination.Entry.IP)
|
if edge.Destination.Entry.Name == UnresolvedNodeName {
|
||||||
|
assert.Equal(edge.Destination.Name, edge.Destination.Entry.IP)
|
||||||
|
} else {
|
||||||
|
assert.Equal(edge.Destination.Name, edge.Destination.Entry.Name)
|
||||||
|
}
|
||||||
assert.Equal(destEntryName, edge.Destination.Entry.Name)
|
assert.Equal(destEntryName, edge.Destination.Entry.Name)
|
||||||
|
|
||||||
// protocol
|
// protocol
|
||||||
|
|||||||
32
cli/Makefile
32
cli/Makefile
@@ -1,3 +1,9 @@
|
|||||||
|
SHELL=/bin/bash
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
|
.ONESHELL:
|
||||||
|
|
||||||
SUFFIX=$(GOOS)_$(GOARCH)
|
SUFFIX=$(GOOS)_$(GOARCH)
|
||||||
COMMIT_HASH=$(shell git rev-parse HEAD)
|
COMMIT_HASH=$(shell git rev-parse HEAD)
|
||||||
GIT_BRANCH=$(shell git branch --show-current | tr '[:upper:]' '[:lower:]')
|
GIT_BRANCH=$(shell git branch --show-current | tr '[:upper:]' '[:lower:]')
|
||||||
@@ -5,26 +11,28 @@ GIT_VERSION=$(shell git branch --show-current | tr '[:upper:]' '[:lower:]')
|
|||||||
BUILD_TIMESTAMP=$(shell date +%s)
|
BUILD_TIMESTAMP=$(shell date +%s)
|
||||||
export VER?=0.0
|
export VER?=0.0
|
||||||
|
|
||||||
.PHONY: help
|
|
||||||
.DEFAULT_GOAL := help
|
|
||||||
|
|
||||||
help: ## This help.
|
help: ## This help.
|
||||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
install:
|
install:
|
||||||
go install mizu.go
|
go install mizu.go
|
||||||
|
|
||||||
build-debug:
|
build-debug: ## Build mizu CLI for debug
|
||||||
export GCLFAGS='-gcflags="all=-N -l"'
|
export GCLFAGS='-gcflags="all=-N -l"'
|
||||||
${MAKE} build
|
${MAKE} build-base
|
||||||
|
|
||||||
build: ## Build mizu CLI binary (select platform via GOOS / GOARCH env variables).
|
build:
|
||||||
go build ${GCLFAGS} -ldflags="-X 'github.com/up9inc/mizu/cli/mizu.GitCommitHash=$(COMMIT_HASH)' \
|
export LDFLAGS_EXT='-s -w'
|
||||||
-X 'github.com/up9inc/mizu/cli/mizu.Branch=$(GIT_BRANCH)' \
|
${MAKE} build-base
|
||||||
-X 'github.com/up9inc/mizu/cli/mizu.BuildTimestamp=$(BUILD_TIMESTAMP)' \
|
|
||||||
-X 'github.com/up9inc/mizu/cli/mizu.Platform=$(SUFFIX)' \
|
build-base: ## Build mizu CLI binary (select platform via GOOS / GOARCH env variables).
|
||||||
-X 'github.com/up9inc/mizu/cli/mizu.Ver=$(VER)'" \
|
go build ${GCLFAGS} -ldflags="${LDFLAGS_EXT} \
|
||||||
-o bin/mizu_$(SUFFIX) mizu.go
|
-X 'github.com/up9inc/mizu/cli/mizu.GitCommitHash=$(COMMIT_HASH)' \
|
||||||
|
-X 'github.com/up9inc/mizu/cli/mizu.Branch=$(GIT_BRANCH)' \
|
||||||
|
-X 'github.com/up9inc/mizu/cli/mizu.BuildTimestamp=$(BUILD_TIMESTAMP)' \
|
||||||
|
-X 'github.com/up9inc/mizu/cli/mizu.Platform=$(SUFFIX)' \
|
||||||
|
-X 'github.com/up9inc/mizu/cli/mizu.Ver=$(VER)'" \
|
||||||
|
-o bin/mizu_$(SUFFIX) mizu.go
|
||||||
(cd bin && shasum -a 256 mizu_${SUFFIX} > mizu_${SUFFIX}.sha256)
|
(cd bin && shasum -a 256 mizu_${SUFFIX} > mizu_${SUFFIX}.sha256)
|
||||||
|
|
||||||
build-all: ## Build for all supported platforms.
|
build-all: ## Build for all supported platforms.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Mizu release _VER_
|
# Mizu release _VER_
|
||||||
Full changelog for stable release see in [docs](https://github.com/up9inc/mizu/blob/main/docs/CHANGELOG.md)
|
Mizu CHANGELOG is now part of [Mizu wiki](https://github.com/up9inc/mizu/wiki/CHANGELOG)
|
||||||
|
|
||||||
## Download Mizu for your platform
|
## Download Mizu for your platform
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin
|
|||||||
|
|
||||||
**Mac** (AArch64/Apple M1 silicon)
|
**Mac** (AArch64/Apple M1 silicon)
|
||||||
```
|
```
|
||||||
curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin_arm64 && chmod 755 mizu
|
rm -f mizu && curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin_arm64 && chmod 755 mizu
|
||||||
```
|
```
|
||||||
|
|
||||||
**Linux** (x86-64)
|
**Linux** (x86-64)
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/shared/kubernetes"
|
"github.com/up9inc/mizu/shared/kubernetes"
|
||||||
@@ -57,10 +59,8 @@ func (provider *Provider) TestConnection() error {
|
|||||||
|
|
||||||
func (provider *Provider) isReachable() (bool, error) {
|
func (provider *Provider) isReachable() (bool, error) {
|
||||||
echoUrl := fmt.Sprintf("%s/echo", provider.url)
|
echoUrl := fmt.Sprintf("%s/echo", provider.url)
|
||||||
if response, err := provider.client.Get(echoUrl); err != nil {
|
if _, err := provider.get(echoUrl); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
} else if response.StatusCode != 200 {
|
|
||||||
return false, fmt.Errorf("invalid status code %v", response.StatusCode)
|
|
||||||
} else {
|
} else {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
@@ -72,10 +72,8 @@ func (provider *Provider) ReportTapperStatus(tapperStatus shared.TapperStatus) e
|
|||||||
if jsonValue, err := json.Marshal(tapperStatus); err != nil {
|
if jsonValue, err := json.Marshal(tapperStatus); err != nil {
|
||||||
return fmt.Errorf("failed Marshal the tapper status %w", err)
|
return fmt.Errorf("failed Marshal the tapper status %w", err)
|
||||||
} else {
|
} else {
|
||||||
if response, err := provider.client.Post(tapperStatusUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil {
|
if _, err := provider.post(tapperStatusUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil {
|
||||||
return fmt.Errorf("failed sending to API server the tapped pods %w", err)
|
return fmt.Errorf("failed sending to API server the tapped pods %w", err)
|
||||||
} else if response.StatusCode != 200 {
|
|
||||||
return fmt.Errorf("failed sending to API server the tapper status, response status code %v", response.StatusCode)
|
|
||||||
} else {
|
} else {
|
||||||
logger.Log.Debugf("Reported to server API about tapper status: %v", tapperStatus)
|
logger.Log.Debugf("Reported to server API about tapper status: %v", tapperStatus)
|
||||||
return nil
|
return nil
|
||||||
@@ -91,10 +89,8 @@ func (provider *Provider) ReportTappedPods(pods []core.Pod) error {
|
|||||||
if jsonValue, err := json.Marshal(podInfos); err != nil {
|
if jsonValue, err := json.Marshal(podInfos); err != nil {
|
||||||
return fmt.Errorf("failed Marshal the tapped pods %w", err)
|
return fmt.Errorf("failed Marshal the tapped pods %w", err)
|
||||||
} else {
|
} else {
|
||||||
if response, err := provider.client.Post(tappedPodsUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil {
|
if _, err := provider.post(tappedPodsUrl, "application/json", bytes.NewBuffer(jsonValue)); err != nil {
|
||||||
return fmt.Errorf("failed sending to API server the tapped pods %w", err)
|
return fmt.Errorf("failed sending to API server the tapped pods %w", err)
|
||||||
} else if response.StatusCode != 200 {
|
|
||||||
return fmt.Errorf("failed sending to API server the tapped pods, response status code %v", response.StatusCode)
|
|
||||||
} else {
|
} else {
|
||||||
logger.Log.Debugf("Reported to server API about %d taped pods successfully", len(podInfos))
|
logger.Log.Debugf("Reported to server API about %d taped pods successfully", len(podInfos))
|
||||||
return nil
|
return nil
|
||||||
@@ -105,11 +101,9 @@ func (provider *Provider) ReportTappedPods(pods []core.Pod) error {
|
|||||||
func (provider *Provider) GetGeneralStats() (map[string]interface{}, error) {
|
func (provider *Provider) GetGeneralStats() (map[string]interface{}, error) {
|
||||||
generalStatsUrl := fmt.Sprintf("%s/status/general", provider.url)
|
generalStatsUrl := fmt.Sprintf("%s/status/general", provider.url)
|
||||||
|
|
||||||
response, requestErr := provider.client.Get(generalStatsUrl)
|
response, requestErr := provider.get(generalStatsUrl)
|
||||||
if requestErr != nil {
|
if requestErr != nil {
|
||||||
return nil, fmt.Errorf("failed to get general stats for telemetry, err: %w", requestErr)
|
return nil, fmt.Errorf("failed to get general stats for telemetry, err: %w", requestErr)
|
||||||
} else if response.StatusCode != 200 {
|
|
||||||
return nil, fmt.Errorf("failed to get general stats for telemetry, status code: %v", response.StatusCode)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
@@ -132,7 +126,7 @@ func (provider *Provider) GetVersion() (string, error) {
|
|||||||
Method: http.MethodGet,
|
Method: http.MethodGet,
|
||||||
URL: versionUrl,
|
URL: versionUrl,
|
||||||
}
|
}
|
||||||
statusResp, err := provider.client.Do(req)
|
statusResp, err := provider.do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -145,3 +139,40 @@ func (provider *Provider) GetVersion() (string, error) {
|
|||||||
|
|
||||||
return versionResponse.Ver, nil
|
return versionResponse.Ver, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When err is nil, resp always contains a non-nil resp.Body.
|
||||||
|
// Caller should close resp.Body when done reading from it.
|
||||||
|
func (provider *Provider) get(url string) (*http.Response, error) {
|
||||||
|
return provider.checkError(provider.client.Get(url))
|
||||||
|
}
|
||||||
|
|
||||||
|
// When err is nil, resp always contains a non-nil resp.Body.
|
||||||
|
// Caller should close resp.Body when done reading from it.
|
||||||
|
func (provider *Provider) post(url, contentType string, body io.Reader) (*http.Response, error) {
|
||||||
|
return provider.checkError(provider.client.Post(url, contentType, body))
|
||||||
|
}
|
||||||
|
|
||||||
|
// When err is nil, resp always contains a non-nil resp.Body.
|
||||||
|
// Caller should close resp.Body when done reading from it.
|
||||||
|
func (provider *Provider) do(req *http.Request) (*http.Response, error) {
|
||||||
|
return provider.checkError(provider.client.Do(req))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (provider *Provider) checkError(response *http.Response, errInOperation error) (*http.Response, error) {
|
||||||
|
if (errInOperation != nil) {
|
||||||
|
return response, errInOperation
|
||||||
|
// Check only if status != 200 (and not status >= 300). Agent APIs return only 200 on success.
|
||||||
|
} else if response.StatusCode != http.StatusOK {
|
||||||
|
body, err := ioutil.ReadAll(response.Body)
|
||||||
|
response.Body.Close()
|
||||||
|
response.Body = io.NopCloser(bytes.NewBuffer(body)) // rewind
|
||||||
|
if err != nil {
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|
||||||
|
errorMsg := strings.ReplaceAll((string(body)), "\n", ";")
|
||||||
|
return response, fmt.Errorf("got response with status code: %d, body: %s", response.StatusCode, errorMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/creasty/defaults"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/up9inc/mizu/cli/config/configStructs"
|
||||||
"github.com/up9inc/mizu/cli/telemetry"
|
"github.com/up9inc/mizu/cli/telemetry"
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkCmd = &cobra.Command{
|
var checkCmd = &cobra.Command{
|
||||||
@@ -17,4 +20,11 @@ var checkCmd = &cobra.Command{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(checkCmd)
|
rootCmd.AddCommand(checkCmd)
|
||||||
|
|
||||||
|
defaultCheckConfig := configStructs.CheckConfig{}
|
||||||
|
if err := defaults.Set(&defaultCheckConfig); err != nil {
|
||||||
|
logger.Log.Debug(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkCmd.Flags().Bool(configStructs.PreTapCheckName, defaultCheckConfig.PreTap, "Check pre-tap Mizu installation for potential problems")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,15 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
core "k8s.io/api/core/v1"
|
||||||
|
rbac "k8s.io/api/rbac/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/cli/apiserver"
|
"github.com/up9inc/mizu/cli/apiserver"
|
||||||
"github.com/up9inc/mizu/cli/config"
|
"github.com/up9inc/mizu/cli/config"
|
||||||
@@ -13,8 +20,13 @@ import (
|
|||||||
"github.com/up9inc/mizu/shared/semver"
|
"github.com/up9inc/mizu/shared/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed permissionFiles
|
||||||
|
embedFS embed.FS
|
||||||
|
)
|
||||||
|
|
||||||
func runMizuCheck() {
|
func runMizuCheck() {
|
||||||
logger.Log.Infof("Mizu install checks\n===================")
|
logger.Log.Infof("Mizu checks\n===================")
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel() // cancel will be called when this function exits
|
defer cancel() // cancel will be called when this function exits
|
||||||
@@ -25,17 +37,22 @@ func runMizuCheck() {
|
|||||||
checkPassed = checkKubernetesVersion(kubernetesVersion)
|
checkPassed = checkKubernetesVersion(kubernetesVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isInstallCommand bool
|
if config.Config.Check.PreTap {
|
||||||
if checkPassed {
|
if checkPassed {
|
||||||
checkPassed, isInstallCommand = checkMizuMode(ctx, kubernetesProvider)
|
checkPassed = checkK8sTapPermissions(ctx, kubernetesProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
if checkPassed {
|
if checkPassed {
|
||||||
checkPassed = checkAllResourcesExist(ctx, kubernetesProvider, isInstallCommand)
|
checkPassed = checkImagePullInCluster(ctx, kubernetesProvider)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if checkPassed {
|
||||||
|
checkPassed = checkK8sResources(ctx, kubernetesProvider)
|
||||||
|
}
|
||||||
|
|
||||||
if checkPassed {
|
if checkPassed {
|
||||||
checkPassed = checkServerConnection(kubernetesProvider)
|
checkPassed = checkServerConnection(kubernetesProvider)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if checkPassed {
|
if checkPassed {
|
||||||
@@ -65,21 +82,6 @@ func checkKubernetesApi() (*kubernetes.Provider, *semver.SemVersion, bool) {
|
|||||||
return kubernetesProvider, kubernetesVersion, true
|
return kubernetesProvider, kubernetesVersion, true
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkMizuMode(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, bool) {
|
|
||||||
logger.Log.Infof("\nmizu-mode\n--------------------")
|
|
||||||
|
|
||||||
if exist, err := kubernetesProvider.DoesDeploymentExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
|
||||||
logger.Log.Errorf("%v can't check mizu command, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
|
||||||
return false, false
|
|
||||||
} else if exist {
|
|
||||||
logger.Log.Infof("%v mizu running with install command", fmt.Sprintf(uiUtils.Green, "√"))
|
|
||||||
return true, true
|
|
||||||
} else {
|
|
||||||
logger.Log.Infof("%v mizu running with tap command", fmt.Sprintf(uiUtils.Green, "√"))
|
|
||||||
return true, false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkKubernetesVersion(kubernetesVersion *semver.SemVersion) bool {
|
func checkKubernetesVersion(kubernetesVersion *semver.SemVersion) bool {
|
||||||
logger.Log.Infof("\nkubernetes-version\n--------------------")
|
logger.Log.Infof("\nkubernetes-version\n--------------------")
|
||||||
|
|
||||||
@@ -93,9 +95,9 @@ func checkKubernetesVersion(kubernetesVersion *semver.SemVersion) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkServerConnection(kubernetesProvider *kubernetes.Provider) bool {
|
func checkServerConnection(kubernetesProvider *kubernetes.Provider) bool {
|
||||||
logger.Log.Infof("\nmizu-connectivity\n--------------------")
|
logger.Log.Infof("\nAPI-server-connectivity\n--------------------")
|
||||||
|
|
||||||
serverUrl := GetApiServerUrl()
|
serverUrl := GetApiServerUrl(config.Config.Tap.GuiPort)
|
||||||
|
|
||||||
apiServerProvider := apiserver.NewProvider(serverUrl, 1, apiserver.DefaultTimeout)
|
apiServerProvider := apiserver.NewProvider(serverUrl, 1, apiserver.DefaultTimeout)
|
||||||
if err := apiServerProvider.TestConnection(); err == nil {
|
if err := apiServerProvider.TestConnection(); err == nil {
|
||||||
@@ -163,8 +165,8 @@ func checkPortForward(serverUrl string, kubernetesProvider *kubernetes.Provider)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkAllResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider, isInstallCommand bool) bool {
|
func checkK8sResources(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||||
logger.Log.Infof("\nmizu-existence\n--------------------")
|
logger.Log.Infof("\nk8s-components\n--------------------")
|
||||||
|
|
||||||
exist, err := kubernetesProvider.DoesNamespaceExist(ctx, config.Config.MizuResourcesNamespace)
|
exist, err := kubernetesProvider.DoesNamespaceExist(ctx, config.Config.MizuResourcesNamespace)
|
||||||
allResourcesExist := checkResourceExist(config.Config.MizuResourcesNamespace, "namespace", exist, err)
|
allResourcesExist := checkResourceExist(config.Config.MizuResourcesNamespace, "namespace", exist, err)
|
||||||
@@ -192,36 +194,47 @@ func checkAllResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.
|
|||||||
exist, err = kubernetesProvider.DoesServiceExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
exist, err = kubernetesProvider.DoesServiceExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
||||||
allResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "service", exist, err) && allResourcesExist
|
allResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "service", exist, err) && allResourcesExist
|
||||||
|
|
||||||
if isInstallCommand {
|
allResourcesExist = checkPodResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
||||||
allResourcesExist = checkInstallResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
|
||||||
} else {
|
|
||||||
allResourcesExist = checkTapResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
|
||||||
}
|
|
||||||
|
|
||||||
return allResourcesExist
|
return allResourcesExist
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkInstallResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
func checkPodResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||||
exist, err := kubernetesProvider.DoesRoleExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.DaemonRoleName)
|
if pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
||||||
installResourcesExist := checkResourceExist(kubernetes.DaemonRoleName, "role", exist, err)
|
logger.Log.Errorf("%v error checking if '%v' pod is running, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName, err)
|
||||||
|
return false
|
||||||
|
} else if len(pods) == 0 {
|
||||||
|
logger.Log.Errorf("%v '%v' pod doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName)
|
||||||
|
return false
|
||||||
|
} else if !kubernetes.IsPodRunning(&pods[0]) {
|
||||||
|
logger.Log.Errorf("%v '%v' pod not running", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
exist, err = kubernetesProvider.DoesRoleBindingExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.DaemonRoleBindingName)
|
logger.Log.Infof("%v '%v' pod running", fmt.Sprintf(uiUtils.Green, "√"), kubernetes.ApiServerPodName)
|
||||||
installResourcesExist = checkResourceExist(kubernetes.DaemonRoleBindingName, "role binding", exist, err) && installResourcesExist
|
|
||||||
|
|
||||||
exist, err = kubernetesProvider.DoesPersistentVolumeClaimExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.PersistentVolumeClaimName)
|
if pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, config.Config.MizuResourcesNamespace, kubernetes.TapperPodName); err != nil {
|
||||||
installResourcesExist = checkResourceExist(kubernetes.PersistentVolumeClaimName, "persistent volume claim", exist, err) && installResourcesExist
|
logger.Log.Errorf("%v error checking if '%v' pods are running, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.TapperPodName, err)
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
tappers := 0
|
||||||
|
notRunningTappers := 0
|
||||||
|
|
||||||
exist, err = kubernetesProvider.DoesDeploymentExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
for _, pod := range pods {
|
||||||
installResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "deployment", exist, err) && installResourcesExist
|
tappers += 1
|
||||||
|
if !kubernetes.IsPodRunning(&pod) {
|
||||||
|
notRunningTappers += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return installResourcesExist
|
if notRunningTappers > 0 {
|
||||||
}
|
logger.Log.Errorf("%v '%v' %v/%v pods are not running", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.TapperPodName, notRunningTappers, tappers)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func checkTapResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
logger.Log.Infof("%v '%v' %v pods running", fmt.Sprintf(uiUtils.Green, "√"), kubernetes.TapperPodName, tappers)
|
||||||
exist, err := kubernetesProvider.DoesPodExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
return true
|
||||||
tapResourcesExist := checkResourceExist(kubernetes.ApiServerPodName, "pod", exist, err)
|
}
|
||||||
|
|
||||||
return tapResourcesExist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkResourceExist(resourceName string, resourceType string, exist bool, err error) bool {
|
func checkResourceExist(resourceName string, resourceType string, exist bool, err error) bool {
|
||||||
@@ -231,9 +244,182 @@ func checkResourceExist(resourceName string, resourceType string, exist bool, er
|
|||||||
} else if !exist {
|
} else if !exist {
|
||||||
logger.Log.Errorf("%v '%v' %v doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), resourceName, resourceType)
|
logger.Log.Errorf("%v '%v' %v doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), resourceName, resourceType)
|
||||||
return false
|
return false
|
||||||
} else {
|
|
||||||
logger.Log.Infof("%v '%v' %v exists", fmt.Sprintf(uiUtils.Green, "√"), resourceName, resourceType)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("%v '%v' %v exists", fmt.Sprintf(uiUtils.Green, "√"), resourceName, resourceType)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkK8sTapPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||||
|
logger.Log.Infof("\nkubernetes-permissions\n--------------------")
|
||||||
|
|
||||||
|
var filePath string
|
||||||
|
if config.Config.IsNsRestrictedMode() {
|
||||||
|
filePath = "permissionFiles/permissions-ns-tap.yaml"
|
||||||
|
} else {
|
||||||
|
filePath = "permissionFiles/permissions-all-namespaces-tap.yaml"
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := embedFS.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, err := getDecodedObject(data)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var rules []rbac.PolicyRule
|
||||||
|
if config.Config.IsNsRestrictedMode() {
|
||||||
|
rules = obj.(*rbac.Role).Rules
|
||||||
|
} else {
|
||||||
|
rules = obj.(*rbac.ClusterRole).Rules
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkPermissions(ctx, kubernetesProvider, rules)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getDecodedObject(data []byte) (runtime.Object, error) {
|
||||||
|
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||||
|
|
||||||
|
obj, _, err := decode(data, nil, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider, rules []rbac.PolicyRule) bool {
|
||||||
|
permissionsExist := true
|
||||||
|
|
||||||
|
for _, rule := range rules {
|
||||||
|
for _, group := range rule.APIGroups {
|
||||||
|
for _, resource := range rule.Resources {
|
||||||
|
for _, verb := range rule.Verbs {
|
||||||
|
exist, err := kubernetesProvider.CanI(ctx, config.Config.MizuResourcesNamespace, resource, verb, group)
|
||||||
|
permissionsExist = checkPermissionExist(group, resource, verb, exist, err) && permissionsExist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissionsExist
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkPermissionExist(group string, resource string, verb string, exist bool, err error) bool {
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf("%v error checking permission for %v %v in group '%v', err: %v", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, group, err)
|
||||||
|
return false
|
||||||
|
} else if !exist {
|
||||||
|
logger.Log.Errorf("%v can't %v %v in group '%v'", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, group)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("%v can %v %v in group '%v'", fmt.Sprintf(uiUtils.Green, "√"), verb, resource, group)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkImagePullInCluster(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||||
|
logger.Log.Infof("\nimage-pull-in-cluster\n--------------------")
|
||||||
|
|
||||||
|
podName := "image-pull-in-cluster"
|
||||||
|
|
||||||
|
defer removeImagePullInClusterResources(ctx, kubernetesProvider, podName)
|
||||||
|
if err := createImagePullInClusterResources(ctx, kubernetesProvider, podName); err != nil {
|
||||||
|
logger.Log.Errorf("%v error while creating image pull in cluster resources, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := checkImagePulled(ctx, kubernetesProvider, podName); err != nil {
|
||||||
|
logger.Log.Errorf("%v cluster is not able to pull mizu containers from docker hub, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Log.Infof("%v cluster is able to pull mizu containers from docker hub", fmt.Sprintf(uiUtils.Green, "√"))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkImagePulled(ctx context.Context, kubernetesProvider *kubernetes.Provider, podName string) error {
|
||||||
|
podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s$", podName))
|
||||||
|
podWatchHelper := kubernetes.NewPodWatchHelper(kubernetesProvider, podExactRegex)
|
||||||
|
eventChan, errorChan := kubernetes.FilteredWatch(ctx, podWatchHelper, []string{config.Config.MizuResourcesNamespace}, podWatchHelper)
|
||||||
|
|
||||||
|
timeAfter := time.After(30 * time.Second)
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case wEvent, ok := <-eventChan:
|
||||||
|
if !ok {
|
||||||
|
eventChan = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
pod, err := wEvent.ToPod()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if pod.Status.Phase == core.PodRunning {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
case err, ok := <-errorChan:
|
||||||
|
if !ok {
|
||||||
|
errorChan = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
case <-timeAfter:
|
||||||
|
return fmt.Errorf("image not pulled in time")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeImagePullInClusterResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, podName string) {
|
||||||
|
if err := kubernetesProvider.RemovePod(ctx, config.Config.MizuResourcesNamespace, podName); err != nil {
|
||||||
|
logger.Log.Debugf("error while removing image pull in cluster resources, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !config.Config.IsNsRestrictedMode() {
|
||||||
|
if err := kubernetesProvider.RemoveNamespace(ctx, config.Config.MizuResourcesNamespace); err != nil {
|
||||||
|
logger.Log.Debugf("error while removing image pull in cluster resources, err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createImagePullInClusterResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, podName string) error {
|
||||||
|
if !config.Config.IsNsRestrictedMode() {
|
||||||
|
if _, err := kubernetesProvider.CreateNamespace(ctx, config.Config.MizuResourcesNamespace); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var zero int64
|
||||||
|
pod := &core.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: podName,
|
||||||
|
},
|
||||||
|
Spec: core.PodSpec{
|
||||||
|
Containers: []core.Container{
|
||||||
|
{
|
||||||
|
Name: "probe",
|
||||||
|
Image: "up9inc/busybox",
|
||||||
|
ImagePullPolicy: "Always",
|
||||||
|
Command: []string{"cat"},
|
||||||
|
Stdin: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TerminationGracePeriodSeconds: &zero,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := kubernetesProvider.CreatePod(ctx, config.Config.MizuResourcesNamespace, pod); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import (
|
|||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetApiServerUrl() string {
|
func GetApiServerUrl(port uint16) string {
|
||||||
return fmt.Sprintf("http://%s", kubernetes.GetMizuApiServerProxiedHostAndPath(config.Config.Tap.GuiPort))
|
return fmt.Sprintf("http://%s", kubernetes.GetMizuApiServerProxiedHostAndPath(port))
|
||||||
}
|
}
|
||||||
|
|
||||||
func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx context.Context, cancel context.CancelFunc) {
|
func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx context.Context, cancel context.CancelFunc, port uint16) {
|
||||||
httpServer, err := kubernetes.StartProxy(kubernetesProvider, config.Config.Tap.ProxyHost, config.Config.Tap.GuiPort, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName, cancel)
|
httpServer, err := kubernetes.StartProxy(kubernetesProvider, config.Config.Tap.ProxyHost, port, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName, cancel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running k8s proxy %v\n"+
|
||||||
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
|
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
|
||||||
@@ -36,7 +36,7 @@ func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx con
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiProvider = apiserver.NewProvider(GetApiServerUrl(), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
apiProvider = apiserver.NewProvider(GetApiServerUrl(port), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
||||||
if err := apiProvider.TestConnection(); err != nil {
|
if err := apiProvider.TestConnection(); err != nil {
|
||||||
logger.Log.Debugf("Couldn't connect using proxy, stopping proxy and trying to create port-forward")
|
logger.Log.Debugf("Couldn't connect using proxy, stopping proxy and trying to create port-forward")
|
||||||
if err := httpServer.Shutdown(ctx); err != nil {
|
if err := httpServer.Shutdown(ctx); err != nil {
|
||||||
@@ -44,14 +44,14 @@ func startProxyReportErrorIfAny(kubernetesProvider *kubernetes.Provider, ctx con
|
|||||||
}
|
}
|
||||||
|
|
||||||
podRegex, _ := regexp.Compile(kubernetes.ApiServerPodName)
|
podRegex, _ := regexp.Compile(kubernetes.ApiServerPodName)
|
||||||
if _, err := kubernetes.NewPortForward(kubernetesProvider, config.Config.MizuResourcesNamespace, podRegex, config.Config.Tap.GuiPort, ctx, cancel); err != nil {
|
if _, err := kubernetes.NewPortForward(kubernetesProvider, config.Config.MizuResourcesNamespace, podRegex, port, ctx, cancel); err != nil {
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running port forward %v\n"+
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error occured while running port forward %v\n"+
|
||||||
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
|
"Try setting different port by using --%s", errormessage.FormatError(err), configStructs.GuiPortTapName))
|
||||||
cancel()
|
cancel()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
apiProvider = apiserver.NewProvider(GetApiServerUrl(), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
apiProvider = apiserver.NewProvider(GetApiServerUrl(port), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
||||||
if err := apiProvider.TestConnection(); err != nil {
|
if err := apiProvider.TestConnection(); err != nil {
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Couldn't connect to API server, for more info check logs at %s", fsUtils.GetLogFilePath()))
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Couldn't connect to API server, for more info check logs at %s", fsUtils.GetLogFilePath()))
|
||||||
cancel()
|
cancel()
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/up9inc/mizu/cli/config"
|
|
||||||
"github.com/up9inc/mizu/cli/telemetry"
|
"github.com/up9inc/mizu/cli/telemetry"
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var installCmd = &cobra.Command{
|
var installCmd = &cobra.Command{
|
||||||
@@ -12,13 +11,13 @@ var installCmd = &cobra.Command{
|
|||||||
Short: "Installs mizu components",
|
Short: "Installs mizu components",
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
go telemetry.ReportRun("install", nil)
|
go telemetry.ReportRun("install", nil)
|
||||||
runMizuInstall()
|
logger.Log.Infof("This command has been deprecated, please use helm as described below.\n\n")
|
||||||
return nil
|
|
||||||
},
|
logger.Log.Infof("To install stable build of Mizu on your cluster using helm, run the following command:")
|
||||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
logger.Log.Infof(" helm install mizu up9mizu --repo https://static.up9.com/mizu/helm --namespace=mizu --create-namespace\n\n")
|
||||||
if config.Config.IsNsRestrictedMode() {
|
|
||||||
return fmt.Errorf("install is not supported in restricted namespace mode")
|
logger.Log.Infof("To install development build of Mizu on your cluster using helm, run the following command:")
|
||||||
}
|
logger.Log.Infof(" helm install mizu up9mizu --repo https://static.up9.com/mizu/helm-develop --namespace=mizu --create-namespace\n")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -27,4 +26,3 @@ var installCmd = &cobra.Command{
|
|||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(installCmd)
|
rootCmd.AddCommand(installCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/creasty/defaults"
|
|
||||||
"github.com/up9inc/mizu/cli/config"
|
|
||||||
"github.com/up9inc/mizu/cli/errormessage"
|
|
||||||
"github.com/up9inc/mizu/cli/resources"
|
|
||||||
"github.com/up9inc/mizu/cli/uiUtils"
|
|
||||||
"github.com/up9inc/mizu/shared"
|
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
|
||||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func runMizuInstall() {
|
|
||||||
kubernetesProvider, err := getKubernetesProviderForCli()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel() // cancel will be called when this function exits
|
|
||||||
|
|
||||||
var serializedValidationRules string
|
|
||||||
var serializedContract string
|
|
||||||
|
|
||||||
var defaultMaxEntriesDBSizeBytes int64 = 200 * 1000 * 1000
|
|
||||||
|
|
||||||
defaultResources := shared.Resources{}
|
|
||||||
if err := defaults.Set(&defaultResources); err != nil {
|
|
||||||
logger.Log.Debug(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
mizuAgentConfig := getInstallMizuAgentConfig(defaultMaxEntriesDBSizeBytes, defaultResources)
|
|
||||||
serializedMizuConfig, err := getSerializedMizuAgentConfig(mizuAgentConfig)
|
|
||||||
if err != nil {
|
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error serializing mizu config: %v", errormessage.FormatError(err)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = resources.CreateInstallMizuResources(ctx, kubernetesProvider, serializedValidationRules,
|
|
||||||
serializedContract, serializedMizuConfig, config.Config.IsNsRestrictedMode(),
|
|
||||||
config.Config.MizuResourcesNamespace, config.Config.AgentImage,
|
|
||||||
config.Config.KratosImage, config.Config.KetoImage,
|
|
||||||
nil, defaultMaxEntriesDBSizeBytes, defaultResources, config.Config.ImagePullPolicy(),
|
|
||||||
config.Config.LogLevel(), false); err != nil {
|
|
||||||
var statusError *k8serrors.StatusError
|
|
||||||
if errors.As(err, &statusError) {
|
|
||||||
if statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists {
|
|
||||||
logger.Log.Info("Mizu is already running in this namespace, run `mizu clean` to remove the currently running Mizu instance")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
defer resources.CleanUpMizuResources(ctx, cancel, kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace)
|
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Log.Infof(uiUtils.Magenta, "Installation completed, run `mizu view` to connect to the mizu daemon instance")
|
|
||||||
}
|
|
||||||
|
|
||||||
func getInstallMizuAgentConfig(maxDBSizeBytes int64, tapperResources shared.Resources) *shared.MizuAgentConfig {
|
|
||||||
mizuAgentConfig := shared.MizuAgentConfig{
|
|
||||||
MaxDBSizeBytes: maxDBSizeBytes,
|
|
||||||
AgentImage: config.Config.AgentImage,
|
|
||||||
PullPolicy: config.Config.ImagePullPolicyStr,
|
|
||||||
LogLevel: config.Config.LogLevel(),
|
|
||||||
TapperResources: tapperResources,
|
|
||||||
MizuResourcesNamespace: config.Config.MizuResourcesNamespace,
|
|
||||||
AgentDatabasePath: shared.DataDirPath,
|
|
||||||
StandaloneMode: true,
|
|
||||||
ServiceMap: config.Config.ServiceMap,
|
|
||||||
OAS: config.Config.OAS,
|
|
||||||
Elastic: config.Config.Elastic,
|
|
||||||
}
|
|
||||||
|
|
||||||
return &mizuAgentConfig
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
# This example shows permissions that enrich the logs with additional info
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-runner-debug-clusterrole
|
||||||
|
rules:
|
||||||
|
- apiGroups: ["events.k8s.io"]
|
||||||
|
resources: ["events"]
|
||||||
|
verbs: ["watch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get"]
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-runner-debug-clusterrolebindings
|
||||||
|
subjects:
|
||||||
|
- kind: User
|
||||||
|
name: user-with-clusterwide-access
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: mizu-runner-debug-clusterrole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# This example shows permissions that are required for Mizu to resolve IPs to service names
|
||||||
|
kind: ClusterRole
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-resolver-clusterrole
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["serviceaccounts"]
|
||||||
|
verbs: ["get", "create"]
|
||||||
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
|
resources: ["clusterroles"]
|
||||||
|
verbs: ["get", "list", "create", "delete"]
|
||||||
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
|
resources: ["clusterrolebindings"]
|
||||||
|
verbs: ["get", "list", "create", "delete"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["services"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["endpoints"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
---
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-resolver-clusterrolebindings
|
||||||
|
subjects:
|
||||||
|
- kind: User
|
||||||
|
name: user-with-clusterwide-access
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: ClusterRole
|
||||||
|
name: mizu-resolver-clusterrole
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in all namespaces with IP resolution disabled.
|
# This example shows the permissions that are required in order to run the `mizu tap` command
|
||||||
# (Traffic will be recorded, but Mizu will not translate IP addresses to names)
|
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
@@ -7,25 +6,25 @@ metadata:
|
|||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["pods"]
|
resources: ["pods"]
|
||||||
verbs: ["list", "watch", "create", "delete"]
|
verbs: ["list", "watch", "create"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["services"]
|
resources: ["services"]
|
||||||
verbs: ["create", "delete"]
|
verbs: ["get", "create"]
|
||||||
- apiGroups: ["apps"]
|
- apiGroups: ["apps"]
|
||||||
resources: ["daemonsets"]
|
resources: ["daemonsets"]
|
||||||
verbs: ["create", "patch", "delete"]
|
verbs: ["create", "patch"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["namespaces"]
|
resources: ["namespaces"]
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
verbs: ["list", "watch", "create", "delete"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["services/proxy"]
|
resources: ["services/proxy"]
|
||||||
verbs: ["get"]
|
verbs: ["get", "create"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["configmaps"]
|
resources: ["configmaps"]
|
||||||
verbs: ["get", "create", "delete"]
|
verbs: ["create"]
|
||||||
- apiGroups: ["events.k8s.io"]
|
- apiGroups: [""]
|
||||||
resources: ["events"]
|
resources: ["pods/log"]
|
||||||
verbs: ["list", "watch"]
|
verbs: ["get"]
|
||||||
---
|
---
|
||||||
kind: ClusterRoleBinding
|
kind: ClusterRoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
@@ -33,7 +32,7 @@ metadata:
|
|||||||
name: mizu-runner-clusterrolebindings
|
name: mizu-runner-clusterrolebindings
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-clusterwide-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: ClusterRole
|
kind: ClusterRole
|
||||||
25
cli/cmd/permissionFiles/permissions-ns-debug-optional.yaml
Normal file
25
cli/cmd/permissionFiles/permissions-ns-debug-optional.yaml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# This example shows permissions that enrich the logs with additional info in namespace-restricted mode
|
||||||
|
kind: Role
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-runner-debug-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: ["events.k8s.io"]
|
||||||
|
resources: ["events"]
|
||||||
|
verbs: ["watch"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get"]
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-runner-debug-rolebindings
|
||||||
|
subjects:
|
||||||
|
- kind: User
|
||||||
|
name: user-with-restricted-access
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: mizu-runner-debug-role
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
# This example shows permissions that are required for Mizu to resolve IPs to service names in namespace-restricted mode
|
||||||
|
kind: Role
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-resolver-role
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["serviceaccounts"]
|
||||||
|
verbs: ["get", "list", "create", "delete"]
|
||||||
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
|
resources: ["roles"]
|
||||||
|
verbs: ["get", "list", "create", "delete"]
|
||||||
|
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||||
|
resources: ["rolebindings"]
|
||||||
|
verbs: ["get", "list", "create", "delete"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["pods"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["services"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
- apiGroups: ["", "apps", "extensions"]
|
||||||
|
resources: ["endpoints"]
|
||||||
|
verbs: ["get", "list", "watch"]
|
||||||
|
---
|
||||||
|
kind: RoleBinding
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
metadata:
|
||||||
|
name: mizu-resolver-rolebindings
|
||||||
|
subjects:
|
||||||
|
- kind: User
|
||||||
|
name: user-with-restricted-access
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
roleRef:
|
||||||
|
kind: Role
|
||||||
|
name: mizu-resolver-role
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
@@ -1,37 +1,35 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in a single namespace with IP resolution disabled.
|
# This example shows the permissions that are required in order to run the `mizu tap` command in namespace-restricted mode
|
||||||
kind: Role
|
kind: Role
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-role
|
name: mizu-runner-role
|
||||||
namespace: user1
|
|
||||||
rules:
|
rules:
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["pods"]
|
resources: ["pods"]
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
verbs: ["list", "watch", "create"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["services"]
|
resources: ["services"]
|
||||||
verbs: ["get", "create", "delete"]
|
verbs: ["get", "create", "delete"]
|
||||||
- apiGroups: ["apps"]
|
- apiGroups: ["apps"]
|
||||||
resources: ["daemonsets"]
|
resources: ["daemonsets"]
|
||||||
verbs: ["get", "create", "patch", "delete"]
|
verbs: ["create", "patch", "delete"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["services/proxy"]
|
resources: ["services/proxy"]
|
||||||
verbs: ["get"]
|
verbs: ["get", "create", "delete"]
|
||||||
- apiGroups: [""]
|
- apiGroups: [""]
|
||||||
resources: ["configmaps"]
|
resources: ["configmaps"]
|
||||||
verbs: ["get", "create", "delete"]
|
verbs: ["create", "delete"]
|
||||||
- apiGroups: ["events.k8s.io"]
|
- apiGroups: [""]
|
||||||
resources: ["events"]
|
resources: ["pods/log"]
|
||||||
verbs: ["list", "watch"]
|
verbs: ["get"]
|
||||||
---
|
---
|
||||||
kind: RoleBinding
|
kind: RoleBinding
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: mizu-runner-rolebindings
|
name: mizu-runner-rolebindings
|
||||||
namespace: user1
|
|
||||||
subjects:
|
subjects:
|
||||||
- kind: User
|
- kind: User
|
||||||
name: user1
|
name: user-with-restricted-access
|
||||||
apiGroup: rbac.authorization.k8s.io
|
apiGroup: rbac.authorization.k8s.io
|
||||||
roleRef:
|
roleRef:
|
||||||
kind: Role
|
kind: Role
|
||||||
@@ -3,9 +3,10 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/up9inc/mizu/cli/up9"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/cli/up9"
|
||||||
|
|
||||||
"github.com/creasty/defaults"
|
"github.com/creasty/defaults"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/up9inc/mizu/cli/auth"
|
"github.com/up9inc/mizu/cli/auth"
|
||||||
@@ -115,9 +116,11 @@ func init() {
|
|||||||
tapCmd.Flags().StringSliceP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies")
|
tapCmd.Flags().StringSliceP(configStructs.PlainTextFilterRegexesTapName, "r", defaultTapConfig.PlainTextFilterRegexes, "List of regex expressions that are used to filter matching values from text/plain http bodies")
|
||||||
tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values")
|
tapCmd.Flags().Bool(configStructs.DisableRedactionTapName, defaultTapConfig.DisableRedaction, "Disables redaction of potentially sensitive request/response headers and body values")
|
||||||
tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "Override the default max entries db size")
|
tapCmd.Flags().String(configStructs.HumanMaxEntriesDBSizeTapName, defaultTapConfig.HumanMaxEntriesDBSize, "Override the default max entries db size")
|
||||||
|
tapCmd.Flags().String(configStructs.InsertionFilterName, defaultTapConfig.InsertionFilter, "Set the insertion filter. Accepts string or a file path.")
|
||||||
tapCmd.Flags().Bool(configStructs.DryRunTapName, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them")
|
tapCmd.Flags().Bool(configStructs.DryRunTapName, defaultTapConfig.DryRun, "Preview of all pods matching the regex, without tapping them")
|
||||||
tapCmd.Flags().StringP(configStructs.WorkspaceTapName, "w", defaultTapConfig.Workspace, "Uploads traffic to your UP9 workspace for further analysis (requires auth)")
|
tapCmd.Flags().StringP(configStructs.WorkspaceTapName, "w", defaultTapConfig.Workspace, "Uploads traffic to your UP9 workspace for further analysis (requires auth)")
|
||||||
tapCmd.Flags().String(configStructs.EnforcePolicyFile, defaultTapConfig.EnforcePolicyFile, "Yaml file path with policy rules")
|
tapCmd.Flags().String(configStructs.EnforcePolicyFile, defaultTapConfig.EnforcePolicyFile, "Yaml file path with policy rules")
|
||||||
tapCmd.Flags().String(configStructs.ContractFile, defaultTapConfig.ContractFile, "OAS/Swagger file to validate to monitor the contracts")
|
tapCmd.Flags().String(configStructs.ContractFile, defaultTapConfig.ContractFile, "OAS/Swagger file to validate to monitor the contracts")
|
||||||
tapCmd.Flags().Bool(configStructs.ServiceMeshName, defaultTapConfig.ServiceMesh, "Record decrypted traffic if the cluster is configured with a service mesh and with mtls")
|
tapCmd.Flags().Bool(configStructs.ServiceMeshName, defaultTapConfig.ServiceMesh, "Record decrypted traffic if the cluster is configured with a service mesh and with mtls")
|
||||||
|
tapCmd.Flags().Bool(configStructs.TlsName, defaultTapConfig.Tls, "Record tls traffic")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ var apiProvider *apiserver.Provider
|
|||||||
func RunMizuTap() {
|
func RunMizuTap() {
|
||||||
state.startTime = time.Now()
|
state.startTime = time.Now()
|
||||||
|
|
||||||
apiProvider = apiserver.NewProvider(GetApiServerUrl(), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
apiProvider = apiserver.NewProvider(GetApiServerUrl(config.Config.Tap.GuiPort), apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
var serializedValidationRules string
|
var serializedValidationRules string
|
||||||
@@ -126,10 +126,8 @@ func RunMizuTap() {
|
|||||||
logger.Log.Infof("Waiting for Mizu Agent to start...")
|
logger.Log.Infof("Waiting for Mizu Agent to start...")
|
||||||
if state.mizuServiceAccountExists, err = resources.CreateTapMizuResources(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace, config.Config.AgentImage, getSyncEntriesConfig(), config.Config.Tap.MaxEntriesDBSizeBytes(), config.Config.Tap.ApiServerResources, config.Config.ImagePullPolicy(), config.Config.LogLevel()); err != nil {
|
if state.mizuServiceAccountExists, err = resources.CreateTapMizuResources(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace, config.Config.AgentImage, getSyncEntriesConfig(), config.Config.Tap.MaxEntriesDBSizeBytes(), config.Config.Tap.ApiServerResources, config.Config.ImagePullPolicy(), config.Config.LogLevel()); err != nil {
|
||||||
var statusError *k8serrors.StatusError
|
var statusError *k8serrors.StatusError
|
||||||
if errors.As(err, &statusError) {
|
if errors.As(err, &statusError) && (statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists) {
|
||||||
if statusError.ErrStatus.Reason == metav1.StatusReasonAlreadyExists {
|
logger.Log.Info("Mizu is already running in this namespace, change the `mizu-resources-namespace` configuration or run `mizu clean` to remove the currently running Mizu instance")
|
||||||
logger.Log.Info("Mizu is already running in this namespace, change the `mizu-resources-namespace` configuration or run `mizu clean` to remove the currently running Mizu instance")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
defer resources.CleanUpMizuResources(ctx, cancel, kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace)
|
defer resources.CleanUpMizuResources(ctx, cancel, kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace)
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err)))
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err)))
|
||||||
@@ -156,6 +154,7 @@ func finishTapExecution(kubernetesProvider *kubernetes.Provider) {
|
|||||||
func getTapMizuAgentConfig() *shared.MizuAgentConfig {
|
func getTapMizuAgentConfig() *shared.MizuAgentConfig {
|
||||||
mizuAgentConfig := shared.MizuAgentConfig{
|
mizuAgentConfig := shared.MizuAgentConfig{
|
||||||
MaxDBSizeBytes: config.Config.Tap.MaxEntriesDBSizeBytes(),
|
MaxDBSizeBytes: config.Config.Tap.MaxEntriesDBSizeBytes(),
|
||||||
|
InsertionFilter: config.Config.Tap.GetInsertionFilter(),
|
||||||
AgentImage: config.Config.AgentImage,
|
AgentImage: config.Config.AgentImage,
|
||||||
PullPolicy: config.Config.ImagePullPolicyStr,
|
PullPolicy: config.Config.ImagePullPolicyStr,
|
||||||
LogLevel: config.Config.LogLevel(),
|
LogLevel: config.Config.LogLevel(),
|
||||||
@@ -164,6 +163,7 @@ func getTapMizuAgentConfig() *shared.MizuAgentConfig {
|
|||||||
AgentDatabasePath: shared.DataDirPath,
|
AgentDatabasePath: shared.DataDirPath,
|
||||||
ServiceMap: config.Config.ServiceMap,
|
ServiceMap: config.Config.ServiceMap,
|
||||||
OAS: config.Config.OAS,
|
OAS: config.Config.OAS,
|
||||||
|
Telemetry: config.Config.Telemetry,
|
||||||
Elastic: config.Config.Elastic,
|
Elastic: config.Config.Elastic,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +202,7 @@ func startTapperSyncer(ctx context.Context, cancel context.CancelFunc, provider
|
|||||||
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
||||||
MizuServiceAccountExists: state.mizuServiceAccountExists,
|
MizuServiceAccountExists: state.mizuServiceAccountExists,
|
||||||
ServiceMesh: config.Config.Tap.ServiceMesh,
|
ServiceMesh: config.Config.Tap.ServiceMesh,
|
||||||
|
Tls: config.Config.Tap.Tls,
|
||||||
}, startTime)
|
}, startTime)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -339,7 +340,7 @@ func watchApiServerPod(ctx context.Context, kubernetesProvider *kubernetes.Provi
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Log.Debugf("Watching API Server pod loop, modified: %v", modifiedPod.Status.Phase)
|
logger.Log.Debugf("Watching API Server pod loop, modified: %v, containers statuses: %v", modifiedPod.Status.Phase, modifiedPod.Status.ContainerStatuses)
|
||||||
|
|
||||||
if modifiedPod.Status.Phase == core.PodRunning && !isPodReady {
|
if modifiedPod.Status.Phase == core.PodRunning && !isPodReady {
|
||||||
isPodReady = true
|
isPodReady = true
|
||||||
@@ -406,7 +407,7 @@ func watchApiServerEvents(ctx context.Context, kubernetesProvider *kubernetes.Pr
|
|||||||
case "FailedScheduling", "Failed":
|
case "FailedScheduling", "Failed":
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Mizu API Server status: %s - %s", event.Reason, event.Note))
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Mizu API Server status: %s - %s", event.Reason, event.Note))
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
}
|
}
|
||||||
case err, ok := <-errorChan:
|
case err, ok := <-errorChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -423,15 +424,15 @@ func watchApiServerEvents(ctx context.Context, kubernetesProvider *kubernetes.Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func postApiServerStarted(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) {
|
func postApiServerStarted(ctx context.Context, kubernetesProvider *kubernetes.Provider, cancel context.CancelFunc) {
|
||||||
startProxyReportErrorIfAny(kubernetesProvider, ctx, cancel)
|
startProxyReportErrorIfAny(kubernetesProvider, ctx, cancel, config.Config.Tap.GuiPort)
|
||||||
|
|
||||||
options, _ := getMizuApiFilteringOptions()
|
options, _ := getMizuApiFilteringOptions()
|
||||||
if err := startTapperSyncer(ctx, cancel, kubernetesProvider, state.targetNamespaces, *options, state.startTime); err != nil {
|
if err := startTapperSyncer(ctx, cancel, kubernetesProvider, state.targetNamespaces, *options, state.startTime); err != nil {
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error starting mizu tapper syncer: %v", err))
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error starting mizu tapper syncer: %v", errormessage.FormatError(err)))
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
url := GetApiServerUrl()
|
url := GetApiServerUrl(config.Config.Tap.GuiPort)
|
||||||
logger.Log.Infof("Mizu is available at %s", url)
|
logger.Log.Infof("Mizu is available at %s", url)
|
||||||
if !config.Config.HeadlessMode {
|
if !config.Config.HeadlessMode {
|
||||||
uiUtils.OpenBrowser(url)
|
uiUtils.OpenBrowser(url)
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/up9inc/mizu/cli/utils"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/cli/utils"
|
||||||
|
|
||||||
"github.com/up9inc/mizu/cli/apiserver"
|
"github.com/up9inc/mizu/cli/apiserver"
|
||||||
"github.com/up9inc/mizu/cli/config"
|
"github.com/up9inc/mizu/cli/config"
|
||||||
"github.com/up9inc/mizu/cli/mizu/fsUtils"
|
"github.com/up9inc/mizu/cli/mizu/fsUtils"
|
||||||
"github.com/up9inc/mizu/cli/mizu/version"
|
|
||||||
"github.com/up9inc/mizu/cli/uiUtils"
|
"github.com/up9inc/mizu/cli/uiUtils"
|
||||||
"github.com/up9inc/mizu/shared/kubernetes"
|
"github.com/up9inc/mizu/shared/kubernetes"
|
||||||
"github.com/up9inc/mizu/shared/logger"
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
@@ -39,7 +39,7 @@ func runMizuView() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
url = GetApiServerUrl()
|
url = GetApiServerUrl(config.Config.View.GuiPort)
|
||||||
|
|
||||||
response, err := http.Get(fmt.Sprintf("%s/", url))
|
response, err := http.Get(fmt.Sprintf("%s/", url))
|
||||||
if err == nil && response.StatusCode == 200 {
|
if err == nil && response.StatusCode == 200 {
|
||||||
@@ -47,7 +47,7 @@ func runMizuView() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
logger.Log.Infof("Establishing connection to k8s cluster...")
|
logger.Log.Infof("Establishing connection to k8s cluster...")
|
||||||
startProxyReportErrorIfAny(kubernetesProvider, ctx, cancel)
|
startProxyReportErrorIfAny(kubernetesProvider, ctx, cancel, config.Config.View.GuiPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
apiServerProvider := apiserver.NewProvider(url, apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
apiServerProvider := apiserver.NewProvider(url, apiserver.DefaultRetries, apiserver.DefaultTimeout)
|
||||||
@@ -62,14 +62,5 @@ func runMizuView() {
|
|||||||
uiUtils.OpenBrowser(url)
|
uiUtils.OpenBrowser(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isCompatible, err := version.CheckVersionCompatibility(apiServerProvider); err != nil {
|
|
||||||
logger.Log.Errorf("Failed to check versions compatibility %v", err)
|
|
||||||
cancel()
|
|
||||||
return
|
|
||||||
} else if !isCompatible {
|
|
||||||
cancel()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.WaitForFinish(ctx, cancel)
|
utils.WaitForFinish(ctx, cancel)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const (
|
|||||||
|
|
||||||
type ConfigStruct struct {
|
type ConfigStruct struct {
|
||||||
Tap configStructs.TapConfig `yaml:"tap"`
|
Tap configStructs.TapConfig `yaml:"tap"`
|
||||||
|
Check configStructs.CheckConfig `yaml:"check"`
|
||||||
Version configStructs.VersionConfig `yaml:"version"`
|
Version configStructs.VersionConfig `yaml:"version"`
|
||||||
View configStructs.ViewConfig `yaml:"view"`
|
View configStructs.ViewConfig `yaml:"view"`
|
||||||
Logs configStructs.LogsConfig `yaml:"logs"`
|
Logs configStructs.LogsConfig `yaml:"logs"`
|
||||||
@@ -38,7 +39,7 @@ type ConfigStruct struct {
|
|||||||
ConfigFilePath string `yaml:"config-path,omitempty" readonly:""`
|
ConfigFilePath string `yaml:"config-path,omitempty" readonly:""`
|
||||||
HeadlessMode bool `yaml:"headless" default:"false"`
|
HeadlessMode bool `yaml:"headless" default:"false"`
|
||||||
LogLevelStr string `yaml:"log-level,omitempty" default:"INFO" readonly:""`
|
LogLevelStr string `yaml:"log-level,omitempty" default:"INFO" readonly:""`
|
||||||
ServiceMap bool `yaml:"service-map" default:"false"`
|
ServiceMap bool `yaml:"service-map" default:"true"`
|
||||||
OAS bool `yaml:"oas,omitempty" default:"false" readonly:""`
|
OAS bool `yaml:"oas,omitempty" default:"false" readonly:""`
|
||||||
Elastic shared.ElasticConfig `yaml:"elastic"`
|
Elastic shared.ElasticConfig `yaml:"elastic"`
|
||||||
}
|
}
|
||||||
|
|||||||
9
cli/config/configStructs/checkConfig.go
Normal file
9
cli/config/configStructs/checkConfig.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package configStructs
|
||||||
|
|
||||||
|
const (
|
||||||
|
PreTapCheckName = "pre-tap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CheckConfig struct {
|
||||||
|
PreTap bool `yaml:"pre-tap"`
|
||||||
|
}
|
||||||
@@ -3,10 +3,16 @@ package configStructs
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/up9inc/mizu/cli/uiUtils"
|
||||||
"github.com/up9inc/mizu/shared"
|
"github.com/up9inc/mizu/shared"
|
||||||
|
|
||||||
|
basenine "github.com/up9inc/basenine/server/lib"
|
||||||
|
"github.com/up9inc/mizu/shared/logger"
|
||||||
"github.com/up9inc/mizu/shared/units"
|
"github.com/up9inc/mizu/shared/units"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -18,33 +24,37 @@ const (
|
|||||||
PlainTextFilterRegexesTapName = "regex-masking"
|
PlainTextFilterRegexesTapName = "regex-masking"
|
||||||
DisableRedactionTapName = "no-redact"
|
DisableRedactionTapName = "no-redact"
|
||||||
HumanMaxEntriesDBSizeTapName = "max-entries-db-size"
|
HumanMaxEntriesDBSizeTapName = "max-entries-db-size"
|
||||||
|
InsertionFilterName = "insertion-filter"
|
||||||
DryRunTapName = "dry-run"
|
DryRunTapName = "dry-run"
|
||||||
WorkspaceTapName = "workspace"
|
WorkspaceTapName = "workspace"
|
||||||
EnforcePolicyFile = "traffic-validation-file"
|
EnforcePolicyFile = "traffic-validation-file"
|
||||||
ContractFile = "contract"
|
ContractFile = "contract"
|
||||||
ServiceMeshName = "service-mesh"
|
ServiceMeshName = "service-mesh"
|
||||||
|
TlsName = "tls"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TapConfig struct {
|
type TapConfig struct {
|
||||||
UploadIntervalSec int `yaml:"upload-interval" default:"10"`
|
UploadIntervalSec int `yaml:"upload-interval" default:"10"`
|
||||||
PodRegexStr string `yaml:"regex" default:".*"`
|
PodRegexStr string `yaml:"regex" default:".*"`
|
||||||
GuiPort uint16 `yaml:"gui-port" default:"8899"`
|
GuiPort uint16 `yaml:"gui-port" default:"8899"`
|
||||||
ProxyHost string `yaml:"proxy-host" default:"127.0.0.1"`
|
ProxyHost string `yaml:"proxy-host" default:"127.0.0.1"`
|
||||||
Namespaces []string `yaml:"namespaces"`
|
Namespaces []string `yaml:"namespaces"`
|
||||||
Analysis bool `yaml:"analysis" default:"false"`
|
Analysis bool `yaml:"analysis" default:"false"`
|
||||||
AllNamespaces bool `yaml:"all-namespaces" default:"false"`
|
AllNamespaces bool `yaml:"all-namespaces" default:"false"`
|
||||||
PlainTextFilterRegexes []string `yaml:"regex-masking"`
|
PlainTextFilterRegexes []string `yaml:"regex-masking"`
|
||||||
IgnoredUserAgents []string `yaml:"ignored-user-agents"`
|
IgnoredUserAgents []string `yaml:"ignored-user-agents"`
|
||||||
DisableRedaction bool `yaml:"no-redact" default:"false"`
|
DisableRedaction bool `yaml:"no-redact" default:"false"`
|
||||||
HumanMaxEntriesDBSize string `yaml:"max-entries-db-size" default:"200MB"`
|
HumanMaxEntriesDBSize string `yaml:"max-entries-db-size" default:"200MB"`
|
||||||
DryRun bool `yaml:"dry-run" default:"false"`
|
InsertionFilter string `yaml:"insertion-filter" default:""`
|
||||||
Workspace string `yaml:"workspace"`
|
DryRun bool `yaml:"dry-run" default:"false"`
|
||||||
EnforcePolicyFile string `yaml:"traffic-validation-file"`
|
Workspace string `yaml:"workspace"`
|
||||||
ContractFile string `yaml:"contract"`
|
EnforcePolicyFile string `yaml:"traffic-validation-file"`
|
||||||
AskUploadConfirmation bool `yaml:"ask-upload-confirmation" default:"true"`
|
ContractFile string `yaml:"contract"`
|
||||||
ApiServerResources shared.Resources `yaml:"api-server-resources"`
|
AskUploadConfirmation bool `yaml:"ask-upload-confirmation" default:"true"`
|
||||||
TapperResources shared.Resources `yaml:"tapper-resources"`
|
ApiServerResources shared.Resources `yaml:"api-server-resources"`
|
||||||
ServiceMesh bool `yaml:"service-mesh" default:"false"`
|
TapperResources shared.Resources `yaml:"tapper-resources"`
|
||||||
|
ServiceMesh bool `yaml:"service-mesh" default:"false"`
|
||||||
|
Tls bool `yaml:"tls" default:"false"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (config *TapConfig) PodRegex() *regexp.Regexp {
|
func (config *TapConfig) PodRegex() *regexp.Regexp {
|
||||||
@@ -57,6 +67,25 @@ func (config *TapConfig) MaxEntriesDBSizeBytes() int64 {
|
|||||||
return maxEntriesDBSizeBytes
|
return maxEntriesDBSizeBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (config *TapConfig) GetInsertionFilter() string {
|
||||||
|
insertionFilter := config.InsertionFilter
|
||||||
|
if fs.ValidPath(insertionFilter) {
|
||||||
|
if _, err := os.Stat(insertionFilter); err == nil {
|
||||||
|
b, err := ioutil.ReadFile(insertionFilter)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Couldn't read the file on path: %s, err: %v", insertionFilter, err))
|
||||||
|
} else {
|
||||||
|
insertionFilter = string(b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_, err := basenine.Parse(insertionFilter)
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Insertion filter syntax error: %v", err))
|
||||||
|
}
|
||||||
|
return insertionFilter
|
||||||
|
}
|
||||||
|
|
||||||
func (config *TapConfig) Validate() error {
|
func (config *TapConfig) Validate() error {
|
||||||
_, compileErr := regexp.Compile(config.PodRegexStr)
|
_, compileErr := regexp.Compile(config.PodRegexStr)
|
||||||
if compileErr != nil {
|
if compileErr != nil {
|
||||||
|
|||||||
100
cli/go.mod
100
cli/go.mod
@@ -1,23 +1,105 @@
|
|||||||
module github.com/up9inc/mizu/cli
|
module github.com/up9inc/mizu/cli
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/creasty/defaults v1.5.1
|
github.com/creasty/defaults v1.5.2
|
||||||
github.com/denisbrodbeck/machineid v1.0.1
|
github.com/denisbrodbeck/machineid v1.0.1
|
||||||
github.com/getkin/kin-openapi v0.79.0
|
github.com/getkin/kin-openapi v0.89.0
|
||||||
github.com/google/go-github/v37 v37.0.0
|
github.com/google/go-github/v37 v37.0.0
|
||||||
github.com/google/uuid v1.1.2
|
github.com/google/uuid v1.3.0
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/spf13/cobra v1.1.3
|
github.com/spf13/cobra v1.3.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
|
github.com/up9inc/basenine/server/lib v0.0.0-20220302073458-c32e0adf1500
|
||||||
github.com/up9inc/mizu/shared v0.0.0
|
github.com/up9inc/mizu/shared v0.0.0
|
||||||
github.com/up9inc/mizu/tap/api v0.0.0
|
github.com/up9inc/mizu/tap/api v0.0.0
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
k8s.io/api v0.22.3
|
k8s.io/api v0.23.3
|
||||||
k8s.io/apimachinery v0.22.3
|
k8s.io/apimachinery v0.23.3
|
||||||
k8s.io/client-go v0.22.3
|
k8s.io/client-go v0.23.3
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go/compute v1.2.0 // indirect
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
|
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest v0.11.24 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||||
|
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||||
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
|
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
|
github.com/alecthomas/participle/v2 v2.0.0-alpha7 // indirect
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||||
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
|
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||||
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||||
|
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||||
|
github.com/ghodss/yaml v1.0.0 // indirect
|
||||||
|
github.com/go-errors/errors v1.4.2 // indirect
|
||||||
|
github.com/go-logr/logr v1.2.2 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.7 // indirect
|
||||||
|
github.com/google/go-querystring v1.1.0 // indirect
|
||||||
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
github.com/google/martian v2.1.0+incompatible // indirect
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
|
github.com/moby/spdystream v0.2.0 // indirect
|
||||||
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
|
github.com/ohler55/ojg v1.12.13 // indirect
|
||||||
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/russross/blackfriday v1.6.0 // indirect
|
||||||
|
github.com/stretchr/testify v1.7.0 // indirect
|
||||||
|
github.com/xlab/treeprint v1.1.0 // indirect
|
||||||
|
go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
k8s.io/cli-runtime v0.23.3 // indirect
|
||||||
|
k8s.io/component-base v0.23.3 // indirect
|
||||||
|
k8s.io/klog/v2 v2.40.1 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||||
|
k8s.io/kubectl v0.23.3 // indirect
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||||
|
sigs.k8s.io/kustomize/api v0.11.1 // indirect
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.13.3 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
replace github.com/up9inc/mizu/shared v0.0.0 => ../shared
|
||||||
|
|||||||
726
cli/go.sum
726
cli/go.sum
File diff suppressed because it is too large
Load Diff
@@ -16,14 +16,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func CreateTapMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, serializedValidationRules string, serializedContract string, serializedMizuConfig string, isNsRestrictedMode bool, mizuResourcesNamespace string, agentImage string, syncEntriesConfig *shared.SyncEntriesConfig, maxEntriesDBSizeBytes int64, apiServerResources shared.Resources, imagePullPolicy core.PullPolicy, logLevel logging.Level) (bool, error) {
|
func CreateTapMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, serializedValidationRules string, serializedContract string, serializedMizuConfig string, isNsRestrictedMode bool, mizuResourcesNamespace string, agentImage string, syncEntriesConfig *shared.SyncEntriesConfig, maxEntriesDBSizeBytes int64, apiServerResources shared.Resources, imagePullPolicy core.PullPolicy, logLevel logging.Level) (bool, error) {
|
||||||
|
mizuServiceAccountExists := false
|
||||||
|
|
||||||
if !isNsRestrictedMode {
|
if !isNsRestrictedMode {
|
||||||
if err := createMizuNamespace(ctx, kubernetesProvider, mizuResourcesNamespace); err != nil {
|
if err := createMizuNamespace(ctx, kubernetesProvider, mizuResourcesNamespace); err != nil {
|
||||||
return false, err
|
return mizuServiceAccountExists, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createMizuConfigmap(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, mizuResourcesNamespace); err != nil {
|
if err := createMizuConfigmap(ctx, kubernetesProvider, serializedValidationRules, serializedContract, serializedMizuConfig, mizuResourcesNamespace); err != nil {
|
||||||
logger.Log.Warningf(uiUtils.Warning, fmt.Sprintf("Failed to create resources required for policy validation. Mizu will not validate policy rules. error: %v", errormessage.FormatError(err)))
|
return mizuServiceAccountExists, err
|
||||||
}
|
}
|
||||||
|
|
||||||
mizuServiceAccountExists, err := createRBACIfNecessary(ctx, kubernetesProvider, isNsRestrictedMode, mizuResourcesNamespace, []string{"pods", "services", "endpoints"})
|
mizuServiceAccountExists, err := createRBACIfNecessary(ctx, kubernetesProvider, isNsRestrictedMode, mizuResourcesNamespace, []string{"pods", "services", "endpoints"})
|
||||||
@@ -157,7 +159,7 @@ func createMizuApiServerDeployment(ctx context.Context, kubernetesProvider *kube
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pod.Spec.Containers[0].LivenessProbe = &core.Probe{
|
pod.Spec.Containers[0].LivenessProbe = &core.Probe{
|
||||||
Handler: core.Handler{
|
ProbeHandler: core.ProbeHandler{
|
||||||
HTTPGet: &core.HTTPGetAction{
|
HTTPGet: &core.HTTPGetAction{
|
||||||
Path: "/echo",
|
Path: "/echo",
|
||||||
Port: intstr.FromInt(shared.DefaultApiServerPort),
|
Port: intstr.FromInt(shared.DefaultApiServerPort),
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
# Patterns to ignore when building packages.
|
|
||||||
# This supports shell glob matching, relative path matching, and
|
|
||||||
# negation (prefixed with !). Only one pattern per line.
|
|
||||||
.DS_Store
|
|
||||||
# Common VCS dirs
|
|
||||||
.git/
|
|
||||||
.gitignore
|
|
||||||
.bzr/
|
|
||||||
.bzrignore
|
|
||||||
.hg/
|
|
||||||
.hgignore
|
|
||||||
.svn/
|
|
||||||
# Common backup files
|
|
||||||
*.swp
|
|
||||||
*.bak
|
|
||||||
*.tmp
|
|
||||||
*.orig
|
|
||||||
*~
|
|
||||||
# Various IDEs
|
|
||||||
.project
|
|
||||||
.idea/
|
|
||||||
*.tmproj
|
|
||||||
.vscode/
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
apiVersion: v2
|
|
||||||
name: mizuhelm
|
|
||||||
description: Mizu helm chart for Kubernetes
|
|
||||||
type: application
|
|
||||||
version: 0.1.1
|
|
||||||
kubeVersion: ">= 1.16.0-0"
|
|
||||||
appVersion: "0.21.29"
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
kind: PersistentVolumeClaim
|
|
||||||
apiVersion: v1
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.volumeClaim.name }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteOnce
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
storage: 700M
|
|
||||||
requests:
|
|
||||||
storage: 700M
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
{{- if .Values.rbac.create -}}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.rbac.name }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
labels:
|
|
||||||
mizu-cli-version: {{ .Chart.AppVersion }}
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "", "extensions", "apps" ]
|
|
||||||
resources: [ "endpoints", "pods", "services", "namespaces" ]
|
|
||||||
verbs: [ "get", "list", "watch" ]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.rbac.roleBindingName }}
|
|
||||||
labels:
|
|
||||||
mizu-cli-version: {{ .Chart.AppVersion }}
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: {{ .Values.rbac.name }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ .Values.serviceAccountName }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
{{- end -}}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.configMap.name }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
data:
|
|
||||||
mizu-config.json: >-
|
|
||||||
{"maxDBSizeBytes":200000000,"agentImage":"{{ .Values.container.tapper.image.repository }}:{{ .Values.container.tapper.image.tag }}","pullPolicy":"Always","logLevel":4,"tapperResources":{"CpuLimit":"750m","MemoryLimit":"1Gi","CpuRequests":"50m","MemoryRequests":"50Mi"},"mizuResourceNamespace":"{{ .Release.Namespace }}","agentDatabasePath":"/app/data/","standaloneMode":true}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.pod.name }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
labels:
|
|
||||||
app: {{ .Values.pod.name }}
|
|
||||||
spec:
|
|
||||||
replicas: {{ .Values.deployment.replicaCount }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ .Values.pod.name }}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.pod.name }}
|
|
||||||
creationTimestamp: null
|
|
||||||
labels:
|
|
||||||
app: {{ .Values.pod.name }}
|
|
||||||
spec:
|
|
||||||
volumes:
|
|
||||||
- name: {{ .Values.configMap.name }}
|
|
||||||
configMap:
|
|
||||||
name: {{ .Values.configMap.name }}
|
|
||||||
defaultMode: 420
|
|
||||||
- name: {{ .Values.volumeClaim.name }}
|
|
||||||
persistentVolumeClaim:
|
|
||||||
claimName: {{ .Values.volumeClaim.name }}
|
|
||||||
containers:
|
|
||||||
- name: {{ .Values.pod.name }}
|
|
||||||
image: "{{ .Values.container.mizuAgent.image.repository }}:{{ .Values.container.mizuAgent.image.tag | default .Chart.AppVersion }}"
|
|
||||||
command:
|
|
||||||
- ./mizuagent
|
|
||||||
- '--api-server'
|
|
||||||
env:
|
|
||||||
- name: SYNC_ENTRIES_CONFIG
|
|
||||||
- name: LOG_LEVEL
|
|
||||||
value: INFO
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 750m
|
|
||||||
memory: 1Gi
|
|
||||||
requests:
|
|
||||||
cpu: 50m
|
|
||||||
memory: 50Mi
|
|
||||||
volumeMounts:
|
|
||||||
- name: {{ .Values.configMap.name }}
|
|
||||||
mountPath: /app/config/
|
|
||||||
- name: {{ .Values.volumeClaim.name }}
|
|
||||||
mountPath: /app/data/
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /echo
|
|
||||||
port: {{ .Values.pod.port }}
|
|
||||||
scheme: HTTP
|
|
||||||
initialDelaySeconds: 1
|
|
||||||
timeoutSeconds: 1
|
|
||||||
periodSeconds: 10
|
|
||||||
successThreshold: 1
|
|
||||||
failureThreshold: 3
|
|
||||||
terminationMessagePath: /dev/termination-log
|
|
||||||
terminationMessagePolicy: File
|
|
||||||
imagePullPolicy: Always
|
|
||||||
- name: {{ .Values.container.basenine.name }}
|
|
||||||
image: "{{ .Values.container.basenine.image.repository }}:{{ .Values.container.basenine.image.tag | default .Chart.AppVersion }}"
|
|
||||||
command:
|
|
||||||
- /basenine
|
|
||||||
args:
|
|
||||||
- '-addr'
|
|
||||||
- 0.0.0.0
|
|
||||||
- '-port'
|
|
||||||
- '9099'
|
|
||||||
- '-persistent'
|
|
||||||
workingDir: /app/data/
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 750m
|
|
||||||
memory: 1Gi
|
|
||||||
requests:
|
|
||||||
cpu: 50m
|
|
||||||
memory: 50Mi
|
|
||||||
volumeMounts:
|
|
||||||
- name: {{ .Values.configMap.name }}
|
|
||||||
mountPath: /app/config/
|
|
||||||
- name: {{ .Values.volumeClaim.name }}
|
|
||||||
mountPath: /app/data/
|
|
||||||
readinessProbe:
|
|
||||||
tcpSocket:
|
|
||||||
port: 9099
|
|
||||||
timeoutSeconds: 1
|
|
||||||
periodSeconds: 1
|
|
||||||
successThreshold: 1
|
|
||||||
failureThreshold: 3
|
|
||||||
terminationMessagePath: /dev/termination-log
|
|
||||||
terminationMessagePolicy: File
|
|
||||||
imagePullPolicy: Always
|
|
||||||
- name: kratos
|
|
||||||
image: "{{ .Values.container.kratos.image.repository }}:{{ .Values.container.kratos.image.tag | default .Chart.AppVersion }}"
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: 750m
|
|
||||||
memory: 1Gi
|
|
||||||
requests:
|
|
||||||
cpu: 50m
|
|
||||||
memory: 50Mi
|
|
||||||
volumeMounts:
|
|
||||||
- name: {{ .Values.configMap.name }}
|
|
||||||
mountPath: /app/config/
|
|
||||||
- name: {{ .Values.volumeClaim.name }}
|
|
||||||
mountPath: /app/data/
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /health/ready
|
|
||||||
port: 4433
|
|
||||||
scheme: HTTP
|
|
||||||
timeoutSeconds: 1
|
|
||||||
periodSeconds: 1
|
|
||||||
successThreshold: 1
|
|
||||||
failureThreshold: 3
|
|
||||||
terminationMessagePath: /dev/termination-log
|
|
||||||
terminationMessagePolicy: File
|
|
||||||
imagePullPolicy: Always
|
|
||||||
restartPolicy: Always
|
|
||||||
terminationGracePeriodSeconds: 0
|
|
||||||
dnsPolicy: ClusterFirstWithHostNet
|
|
||||||
serviceAccountName: {{ .Values.serviceAccountName }}
|
|
||||||
serviceAccount: {{ .Values.serviceAccountName }}
|
|
||||||
securityContext: { }
|
|
||||||
schedulerName: default-scheduler
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.roleName }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
labels:
|
|
||||||
mizu-cli-version: {{ .Chart.AppVersion }}
|
|
||||||
rules:
|
|
||||||
- apiGroups: [ "apps" ]
|
|
||||||
resources: [ "daemonsets" ]
|
|
||||||
verbs: [ "patch", "get", "list", "create", "delete" ]
|
|
||||||
- apiGroups: [ "events.k8s.i" ]
|
|
||||||
resources: [ "events" ]
|
|
||||||
verbs: [ "list", "watch" ]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.roleBindingName }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: {{ .Values.roleName }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ .Values.serviceAccountName }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
---
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.service.name }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
spec:
|
|
||||||
type: {{ .Values.service.type }}
|
|
||||||
ports:
|
|
||||||
- name: api
|
|
||||||
port: {{ .Values.service.port }}
|
|
||||||
targetPort: {{ .Values.pod.port }}
|
|
||||||
protocol: TCP
|
|
||||||
selector:
|
|
||||||
app: {{ .Values.pod.name }}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: {{ .Values.serviceAccountName }}
|
|
||||||
namespace: {{ .Release.Namespace }}
|
|
||||||
labels:
|
|
||||||
mizu-cli-version: {{ .Chart.AppVersion }}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
# Default values for mizu.
|
|
||||||
rbac:
|
|
||||||
create: true
|
|
||||||
name: "mizu-cluster-role"
|
|
||||||
roleBindingName: "mizu-role-binding"
|
|
||||||
|
|
||||||
serviceAccountName: "mizu-service-account"
|
|
||||||
|
|
||||||
roleName: "mizu-role-daemon"
|
|
||||||
roleBindingName: "mizu-role-binding-daemon"
|
|
||||||
|
|
||||||
service:
|
|
||||||
name: "mizu-api-server"
|
|
||||||
type: ClusterIP
|
|
||||||
port: 80
|
|
||||||
|
|
||||||
pod:
|
|
||||||
name: "mizu-api-server"
|
|
||||||
port: 8899
|
|
||||||
|
|
||||||
container:
|
|
||||||
mizuAgent:
|
|
||||||
image:
|
|
||||||
repository: "gcr.io/up9-docker-hub/mizu/main"
|
|
||||||
tag: "0.22.0"
|
|
||||||
tapper:
|
|
||||||
image:
|
|
||||||
repository: "gcr.io/up9-docker-hub/mizu/main"
|
|
||||||
tag: "0.22.0"
|
|
||||||
basenine:
|
|
||||||
name: "basenine"
|
|
||||||
port: 9099
|
|
||||||
image:
|
|
||||||
repository: "ghcr.io/up9inc/basenine"
|
|
||||||
tag: "v0.3.0"
|
|
||||||
kratos:
|
|
||||||
name: "kratos"
|
|
||||||
port: 4433
|
|
||||||
image:
|
|
||||||
repository: "gcr.io/up9-docker-hub/mizu-kratos/stable"
|
|
||||||
tag: "0.0.0"
|
|
||||||
|
|
||||||
deployment:
|
|
||||||
replicaCount: 1
|
|
||||||
|
|
||||||
configMap:
|
|
||||||
name: "mizu-config"
|
|
||||||
|
|
||||||
volumeClaim:
|
|
||||||
create: true
|
|
||||||
name: "mizu-volume-claim"
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
FROM dockcross/linux-arm64-musl:latest AS builder-from-amd64-to-arm64v8
|
FROM dockcross/linux-arm64-musl:latest AS builder-from-amd64-to-arm64v8
|
||||||
|
|
||||||
# Install Go
|
# Install Go
|
||||||
RUN curl https://go.dev/dl/go1.16.13.linux-amd64.tar.gz -Lo ./go.linux-amd64.tar.gz
|
RUN curl https://go.dev/dl/go1.17.6.linux-amd64.tar.gz -Lo ./go.linux-amd64.tar.gz
|
||||||
RUN curl https://go.dev/dl/go1.16.13.linux-amd64.tar.gz.asc -Lo ./go.linux-amd64.tar.gz.asc
|
RUN curl https://go.dev/dl/go1.17.6.linux-amd64.tar.gz.asc -Lo ./go.linux-amd64.tar.gz.asc
|
||||||
RUN curl https://dl.google.com/dl/linux/linux_signing_key.pub -Lo linux_signing_key.pub
|
RUN curl https://dl.google.com/dl/linux/linux_signing_key.pub -Lo linux_signing_key.pub
|
||||||
RUN gpg --import linux_signing_key.pub && gpg --verify ./go.linux-amd64.tar.gz.asc ./go.linux-amd64.tar.gz
|
RUN gpg --import linux_signing_key.pub && gpg --verify ./go.linux-amd64.tar.gz.asc ./go.linux-amd64.tar.gz
|
||||||
RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go.linux-amd64.tar.gz
|
RUN rm -rf /usr/local/go && tar -C /usr/local -xzf go.linux-amd64.tar.gz
|
||||||
|
|||||||
@@ -1,72 +1 @@
|
|||||||
# CHANGELOG
|
Mizu CHANGELOG is now part of [Mizu wiki](https://github.com/up9inc/mizu/wiki/CHANGELOG)
|
||||||
This document summarizes main and fixes changes published in stable (aka `main`) branch of this project.
|
|
||||||
Ongoing work and development releases are under `develop` branch.
|
|
||||||
|
|
||||||
## 0.24.0
|
|
||||||
|
|
||||||
### main features
|
|
||||||
* ARM64 support -- Mizu is now available for ARM 64bit architecture
|
|
||||||
* Now you can run Mizu with `minikube` on your Apple M1 laptop or any other ARM-based hosts
|
|
||||||
* New command helps user verify Mizu deployment
|
|
||||||
* Run `mizu check` to verify Mizu was deployed successfully
|
|
||||||
* `mizu check` verifies version compatibility, resources and permissions required by Mizu
|
|
||||||
* EXPERIMENTAL: Service Map - graph of all service interactions
|
|
||||||
* Arrow direction show client to server connection
|
|
||||||
* Graph edge width reflects volume of traffic captured between the services
|
|
||||||
* to enable this experimental feature use `--set service-map=true` flag
|
|
||||||
|
|
||||||
### improvements
|
|
||||||
* Mizu container images are now served from [Docker Hub](https://hub.docker.com/r/up9inc/mizu), as multi-architecture images (arm64, amd64)
|
|
||||||
* in Mizu GUI the filter query can now be applied by pressing CONTROL/COMMAND + ENTER
|
|
||||||
* try port-forwarding if http-proxy connection to Mizu API server is not available
|
|
||||||
|
|
||||||
### notable bug fixes
|
|
||||||
* Fixed HTTP/1.0 presentation which was shown as HTTP/1.1
|
|
||||||
* Fixed handling of long-living TCP connections, improves capturing gRPC and HTTP/2 traffic, and helps in service-mesh setups (istio, linkerd)
|
|
||||||
|
|
||||||
|
|
||||||
## 0.23.0
|
|
||||||
### notable bug fixes
|
|
||||||
* fixed errors in Redis protocol parser (better handling of Array and Bulk String message types)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 0.22.0
|
|
||||||
|
|
||||||
### main features
|
|
||||||
* Service Mesh support -- mizu is now capable to tap mTLS traffic between pods connected by Istio service mesh
|
|
||||||
* Use `--service-mesh` option to enable this feature
|
|
||||||
* New installation option - have the same Mizu functionality as long living pods in your cluster, with password protection
|
|
||||||
* To install use `mizu install` command
|
|
||||||
* To access use `mizu view` or `kubectl -n mizu port-forward svc/mizu-api-server`
|
|
||||||
* To uninstall run `mizu clean`
|
|
||||||
* At first login
|
|
||||||
* Set admin password as prompted, use it to login to mizu later on.
|
|
||||||
* After login, user should select cluster namespaces to tap: by default all namespaces in the cluster are selected, user can select/unselect according to their needs. These settings are retained and can be modified at any time via Settings menu (cog icon on the top-right)
|
|
||||||
|
|
||||||
|
|
||||||
### improvements
|
|
||||||
* improved Mizu permissions/roles logic to support clusters with strict PodSecurityPolicy (PSP) -- see [PERMISSIONS](PERMISSIONS.md) doc for more details
|
|
||||||
|
|
||||||
### notable bug fixes
|
|
||||||
* mizu now works properly when API service is exposed via HTTPS url
|
|
||||||
* mizu now properly displays KAFKA message body
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## 0.21.0
|
|
||||||
|
|
||||||
### main features
|
|
||||||
* New traffic search & stream exprience
|
|
||||||
* Rich query language with full-text search capabilities on headers & body
|
|
||||||
* Distinct live-streaming vs paging/browsing modes, all with filter applied
|
|
||||||
|
|
||||||
### improvements
|
|
||||||
* GUI - source and destination IP addresses & service names for each traffic item
|
|
||||||
* GUI - Mizu health - display warning sign in top bar when not all requested pods are successfully tapped
|
|
||||||
* GUI - pod tapping status reflected in the list (ok or problem)
|
|
||||||
* Mizu telemetry - report platform type
|
|
||||||
|
|
||||||
### fixes
|
|
||||||
* Request duration and body size properly shown in GUI (instead of -1)
|
|
||||||
|
|||||||
@@ -80,327 +80,9 @@ Notes:
|
|||||||
|
|
||||||
## List of permissions
|
## List of permissions
|
||||||
|
|
||||||
We broke down this list into few categories:
|
The permissions that are required to run Mizu depend on the configuration.
|
||||||
|
By default Mizu requires cluster-wide permissions.
|
||||||
|
If these are not available to the user, it is possible to run Mizu in namespace-restricted mode which has a reduced set of requirements.
|
||||||
|
This is done by by setting the `mizu-resources-namespace` config option. See [configuration](CONFIGURATION.md) for instructions.
|
||||||
|
|
||||||
- Required - what is needed for `mizu` to run properly on your k8s cluster
|
The different requirements are listed in [the permission templates dir](../cli/cmd/permissionFiles)
|
||||||
- Optional - permissions needed for proper name resolving for service & pod IPs
|
|
||||||
- addition required for policy validation
|
|
||||||
|
|
||||||
### Required permissions
|
|
||||||
|
|
||||||
Mizu needs following permissions on your Kubernetes cluster to run properly
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- patch
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- namespaces
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services/proxy
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Permissions required running with install command or (optional) for service / pod name resolving
|
|
||||||
|
|
||||||
Mandatory permissions for running with install command.
|
|
||||||
|
|
||||||
Optional for service/pod name resolving in non install standalone
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- patch
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- namespaces
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services/proxy
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- serviceaccounts
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- clusterroles
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- clusterrolebindings
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- roles
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- rolebindings
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- endpoints
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Permissions for Policy rules validation feature (opt)
|
|
||||||
|
|
||||||
Optionally, in order to use the policy rules validation feature, Mizu requires the following additional permissions:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- configmaps
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
```
|
|
||||||
|
|
||||||
- - -
|
|
||||||
|
|
||||||
#### Namespace-Restricted mode
|
|
||||||
|
|
||||||
Alternatively, in order to restrict Mizu to one namespace only (by setting `agent.namespace` in the config file), Mizu needs the following permissions in that namespace:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- patch
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services/proxy
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Name resolving in Namespace-Restricted mode (opt)
|
|
||||||
|
|
||||||
To restrict Mizu to one namespace while also resolving IPs, Mizu needs the following permissions in that namespace:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- daemonsets
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- patch
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services/proxy
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- serviceaccounts
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- roles
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- rbac.authorization.k8s.io
|
|
||||||
resources:
|
|
||||||
- rolebindings
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
- apps
|
|
||||||
- extensions
|
|
||||||
resources:
|
|
||||||
- endpoints
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,67 +0,0 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in all namespaces.
|
|
||||||
kind: ClusterRole
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-clusterrole
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch", "delete"]
|
|
||||||
- apiGroups: [ "apps" ]
|
|
||||||
resources: [ "deployments" ]
|
|
||||||
verbs: [ "get", "create", "delete" ]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources: ["daemonsets"]
|
|
||||||
verbs: ["get", "create", "patch", "delete", "list"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["namespaces"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/proxy"]
|
|
||||||
verbs: ["get"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["configmaps"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["serviceaccounts"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["clusterroles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["clusterrolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["roles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["rolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["", "apps", "extensions"]
|
|
||||||
resources: ["endpoints"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["events.k8s.io"]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["list", "watch"]
|
|
||||||
---
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-clusterrolebindings
|
|
||||||
subjects:
|
|
||||||
- kind: User
|
|
||||||
name: user1
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mizu-runner-clusterrole
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in all namespaces.
|
|
||||||
kind: ClusterRole
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-clusterrole
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources: ["daemonsets"]
|
|
||||||
verbs: ["create", "patch", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["namespaces"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/proxy"]
|
|
||||||
verbs: ["get"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["configmaps"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["serviceaccounts"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["clusterroles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["clusterrolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["roles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["rolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["", "apps", "extensions"]
|
|
||||||
resources: ["endpoints"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["events.k8s.io"]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["list", "watch"]
|
|
||||||
---
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-clusterrolebindings
|
|
||||||
subjects:
|
|
||||||
- kind: User
|
|
||||||
name: user1
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mizu-runner-clusterrole
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
|
|
||||||
kind: Role
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-role
|
|
||||||
namespace: user1
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch", "delete"]
|
|
||||||
- apiGroups: [ "apps" ]
|
|
||||||
resources: [ "deployments" ]
|
|
||||||
verbs: [ "get", "create", "delete" ]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources: ["daemonsets"]
|
|
||||||
verbs: ["get", "create", "patch", "delete", "list"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/proxy"]
|
|
||||||
verbs: ["get"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["configmaps"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["serviceaccounts"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["roles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["rolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["apps", "extensions", ""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["", "apps", "extensions"]
|
|
||||||
resources: ["endpoints"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["events.k8s.io"]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["list", "watch"]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-rolebindings
|
|
||||||
namespace: user1
|
|
||||||
subjects:
|
|
||||||
- kind: User
|
|
||||||
name: user1
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: mizu-runner-role
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
|
|
||||||
kind: Role
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-role
|
|
||||||
namespace: user1
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources: ["daemonsets"]
|
|
||||||
verbs: ["get", "create", "patch", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/proxy"]
|
|
||||||
verbs: ["get"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["configmaps"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["serviceaccounts"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["roles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["rolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["", "apps", "extensions"]
|
|
||||||
resources: ["endpoints"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["events.k8s.io"]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["list", "watch"]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-rolebindings
|
|
||||||
namespace: user1
|
|
||||||
subjects:
|
|
||||||
- kind: User
|
|
||||||
name: user1
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: mizu-runner-role
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
|
|
||||||
kind: Role
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-role
|
|
||||||
namespace: user1
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "delete"]
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources: ["daemonsets"]
|
|
||||||
verbs: ["get", "create", "patch", "delete"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/proxy"]
|
|
||||||
verbs: ["get"]
|
|
||||||
- apiGroups: [ "" ]
|
|
||||||
resources: [ "configmaps" ]
|
|
||||||
verbs: [ "get", "create", "delete" ]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["serviceaccounts"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["roles"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
|
||||||
resources: ["rolebindings"]
|
|
||||||
verbs: ["get", "create", "delete"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["pods"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["apps", "extensions"]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["", "apps", "extensions"]
|
|
||||||
resources: ["endpoints"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: ["events.k8s.io"]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["list", "watch"]
|
|
||||||
---
|
|
||||||
kind: RoleBinding
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: mizu-runner-rolebindings
|
|
||||||
namespace: user1
|
|
||||||
subjects:
|
|
||||||
- kind: User
|
|
||||||
name: user1
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
roleRef:
|
|
||||||
kind: Role
|
|
||||||
name: mizu-runner-role
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
2
shared/Makefile
Normal file
2
shared/Makefile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
test: ## Run shared tests.
|
||||||
|
@go test ./... -coverpkg=./... -race -coverprofile=coverage.out -covermode=atomic
|
||||||
@@ -1,17 +1,94 @@
|
|||||||
module github.com/up9inc/mizu/shared
|
module github.com/up9inc/mizu/shared
|
||||||
|
|
||||||
go 1.16
|
go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/golang-jwt/jwt/v4 v4.1.0
|
github.com/golang-jwt/jwt/v4 v4.2.0
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/up9inc/mizu/tap/api v0.0.0
|
github.com/up9inc/mizu/tap/api v0.0.0
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
k8s.io/api v0.21.2
|
k8s.io/api v0.23.3
|
||||||
k8s.io/apimachinery v0.21.2
|
k8s.io/apimachinery v0.23.3
|
||||||
k8s.io/client-go v0.21.2
|
k8s.io/client-go v0.23.3
|
||||||
k8s.io/kubectl v0.21.2
|
k8s.io/kubectl v0.23.3
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go/compute v1.2.0 // indirect
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
|
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest v0.11.24 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/adal v0.9.18 // indirect
|
||||||
|
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||||
|
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||||
|
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||||
|
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||||
|
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||||
|
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||||
|
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||||
|
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
|
||||||
|
github.com/fvbommel/sortorder v1.0.2 // indirect
|
||||||
|
github.com/go-errors/errors v1.4.2 // indirect
|
||||||
|
github.com/go-logr/logr v1.2.2 // indirect
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||||
|
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||||
|
github.com/go-openapi/swag v0.21.1 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.2 // indirect
|
||||||
|
github.com/google/btree v1.0.1 // indirect
|
||||||
|
github.com/google/go-cmp v0.5.7 // indirect
|
||||||
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
github.com/google/martian v2.1.0+incompatible // indirect
|
||||||
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||||
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
|
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||||
|
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
|
||||||
|
github.com/imdario/mergo v0.3.12 // indirect
|
||||||
|
github.com/inconshreveable/mousetrap v1.0.0 // indirect
|
||||||
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||||
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
|
github.com/moby/spdystream v0.2.0 // indirect
|
||||||
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||||
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
|
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||||
|
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||||
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||||
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/russross/blackfriday v1.6.0 // indirect
|
||||||
|
github.com/spf13/cobra v1.3.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/stretchr/testify v1.7.0 // indirect
|
||||||
|
github.com/xlab/treeprint v1.1.0 // indirect
|
||||||
|
go.starlark.net v0.0.0-20220203230714-bb14e151c28f // indirect
|
||||||
|
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab // indirect
|
||||||
|
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||||
|
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||||
|
golang.org/x/text v0.3.7 // indirect
|
||||||
|
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||||
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
google.golang.org/protobuf v1.27.1 // indirect
|
||||||
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
k8s.io/cli-runtime v0.23.3 // indirect
|
||||||
|
k8s.io/component-base v0.23.3 // indirect
|
||||||
|
k8s.io/klog/v2 v2.40.1 // indirect
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||||
|
k8s.io/utils v0.0.0-20220127004650-9b3446523e65 // indirect
|
||||||
|
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||||
|
sigs.k8s.io/kustomize/api v0.11.1 // indirect
|
||||||
|
sigs.k8s.io/kustomize/kyaml v0.13.3 // indirect
|
||||||
|
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||||
|
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/up9inc/mizu/tap/api v0.0.0 => ../tap/api
|
replace github.com/up9inc/mizu/tap/api v0.0.0 => ../tap/api
|
||||||
|
|||||||
743
shared/go.sum
743
shared/go.sum
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user