diff --git a/.circleci/config.yaml b/.circleci/config.yaml
new file mode 100644
index 00000000..01b127a2
--- /dev/null
+++ b/.circleci/config.yaml
@@ -0,0 +1,68 @@
+# Golang CircleCI 2.0 configuration file
+#
+# Check https://circleci.com/docs/2.0/language-go/ for more details
+
+version: 2
+jobs:
+ markdownlint-misspell-shellcheck:
+ docker:
+ # this image is build from Dockerfile
+ # https://github.com/pouchcontainer/pouchlinter/blob/master/Dockerfile
+ - image: pouchcontainer/pouchlinter:v0.2.1
+ working_directory: /go/src/github.com/alibaba/pouch
+ steps:
+ - checkout
+ - run:
+ name: use markdownlint v0.5.0 to lint markdown file (https://github.com/markdownlint/markdownlint)
+ command: |
+ find ./ -name "*.md" | grep -v vendor | grep -v commandline | grep -v .github | grep -v swagger | grep -v api | xargs mdl -r ~MD010,~MD013,~MD024,~MD029,~MD033,~MD036
+ - run:
+ name: use markdown-link-check(https://github.com/tcort/markdown-link-check) to check links in markdown files
+ command: |
+ set +e
+ for name in $(find . -name \*.md | grep -v vendor | grep -v CHANGELOG); do
+ if [ -f $name ]; then
+ markdown-link-check -q $name;
+ if [ $? -ne 0 ]; then
+ code=1
+ fi
+ fi
+ done
+ bash -c "exit $code";
+ - run:
+ name: use opensource tool client9/misspell to correct commonly misspelled English words
+ command: |
+ find ./* -name "*" | grep -v vendor | xargs misspell -error
+ - run:
+ name: use ShellCheck (https://github.com/koalaman/shellcheck) to check the validateness of shell scripts in pouch repo
+ command: |
+ find ./ -name "*.sh" | grep -v vendor | xargs shellcheck
+ code-check:
+ docker:
+ - image: pouchcontainer/pouchlinter:v0.2.1
+ working_directory: /go/src/github.com/alibaba/pouch
+ steps:
+ - checkout
+ - run:
+ name: validate swagger.yml
+ command: |
+ swagger validate "/go/src/github.com/alibaba/pouch/apis/swagger.yml"
+ - run:
+ name: validate go code with gometalinter
+ command: |
+ gometalinter --disable-all --skip vendor -E gofmt -E goimports -E golint -E goconst -E ineffassign -E misspell -E vet -d ./...
+
+ - run:
+ name: detect deadcode without test folder
+ command: |
+ gometalinter --disable-all --skip vendor --skip test -E deadcode -d ./...
+notify:
+ webhooks:
+ - url: http://47.96.190.121:6788/circleci_notifications
+
+workflows:
+ version: 2
+ ci:
+ jobs:
+ - markdownlint-misspell-shellcheck
+ - code-check
\ No newline at end of file
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..85e408ce
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,15 @@
+*
+!pkg
+!cmd
+!test
+
+!go.mod
+!go.sum
+
+pkg/dashboard/ui/node_modules
+pkg/dashboard/ui/dist
+
+**/Dockerfile
+**/Dockerfile.alpine
+
+pkg/processor/runtime/python/**/venv
\ No newline at end of file
diff --git a/.env b/.env
new file mode 100644
index 00000000..ce94c3a1
--- /dev/null
+++ b/.env
@@ -0,0 +1,3 @@
+ENV1=localhost:6379
+ENV2=1337
+ADDR=localhost:7777
\ No newline at end of file
diff --git a/.gebug/Dockerfile b/.gebug/Dockerfile
new file mode 100644
index 00000000..45d1806e
--- /dev/null
+++ b/.gebug/Dockerfile
@@ -0,0 +1,9 @@
+FROM golang:1.14
+RUN go get github.com/githubnemo/CompileDaemon
+RUN go get github.com/go-delve/delve/cmd/dlv
+
+WORKDIR /src
+COPY . .
+
+RUN go build -gcflags="all=-N -l" -o /build/package
+ENTRYPOINT dlv --listen=:8888 --headless=true --api-version=2 --accept-multiclient exec /build/package
\ No newline at end of file
diff --git a/.gebug/config.yaml b/.gebug/config.yaml
new file mode 100644
index 00000000..cba60087
--- /dev/null
+++ b/.gebug/config.yaml
@@ -0,0 +1,10 @@
+name: tt
+output_binary: /build/package
+build_command: go build -o {{.output_binary}}
+run_command: '{{.output_binary}}'
+runtime_image: golang:1.14
+debugger_enabled: true
+debugger_port: 8888
+expose_ports: []
+networks: []
+environment: []
diff --git a/.gebug/docker-compose.yml b/.gebug/docker-compose.yml
new file mode 100644
index 00000000..2bcaea4c
--- /dev/null
+++ b/.gebug/docker-compose.yml
@@ -0,0 +1,11 @@
+version: '3'
+services:
+ gebug-tt:
+ build:
+ context: ..
+ dockerfile: .gebug/Dockerfile
+ cap_add:
+ - SYS_PTRACE
+ volumes:
+ - ../:/src:ro
+ - 8888:8888
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..4b16f597
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/codeql/codql-config.yml b/.github/codeql/codql-config.yml
new file mode 100644
index 00000000..1c9de0cd
--- /dev/null
+++ b/.github/codeql/codql-config.yml
@@ -0,0 +1,14 @@
+name: "CodeQL config"
+queries:
+ - name: Run custom queries
+ uses: ./queries
+ # Run all extra query suites, both because we want to
+ # and because it'll act as extra testing. This is why
+ # we include both even though one is a superset of the
+ # other, because we're testing the parsing logic and
+ # that the suites exist in the codeql bundle.
+ - uses: security-extended
+ - uses: security-and-quality
+paths-ignore:
+ - tests
+ - lib
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..4027f7c6
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,31 @@
+# To get started with Dependabot version updates, you'll need to specify which
+# package ecosystems to update and where the package manifests are located.
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+ - package-ecosystem: "github-actions" # See documentation for possible values
+ directory: "/" # Location of package manifests
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "docker"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "gitsubmodule"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "gomod"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "maven"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ - package-ecosystem: "npm"
+ directory: "/"
+ schedule:
+ interval: "daily"
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..eef8cc1d
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,24 @@
+name: Go Build
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ go-version: [1.14.x, 1.15.x]
+ os: [ubuntu-latest]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go-version }}
+ - name: Checkout code
+ uses: actions/checkout@v3.1.0
+ - name: Checkout submodules
+ uses: textbook/git-checkout-submodule-action@master
+ with:
+ remote: true
+ - name: build
+ run: go build ./...
\ No newline at end of file
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
new file mode 100644
index 00000000..e1fdf0ae
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,59 @@
+name: "CodeQL"
+
+on:
+ push:
+ branches: [master, ]
+ pull_request:
+ # The branches below must be a subset of the branches above
+ branches: [master]
+ schedule:
+ - cron: '0 15 * * 0'
+
+jobs:
+ analyze:
+ name: Analyze
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3.1.0
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
+
+ # If this run was triggered by a pull request event, then checkout
+ # the head of the pull request instead of the merge commit.
+ - run: git checkout HEAD^2
+ if: ${{ github.event_name == 'pull_request' }}
+
+ - name: Checkout submodules
+ uses: textbook/git-checkout-submodule-action@master
+ with:
+ remote: true
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ # Override language selection by uncommenting this and choosing your languages
+ # with:
+ # languages: go, javascript, csharp, python, cpp, java
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # โน๏ธ Command-line programs to run using the OS shell.
+ # ๐ https://git.io/JvXDl
+
+ # โ๏ธ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml
new file mode 100644
index 00000000..dded9c13
--- /dev/null
+++ b/.github/workflows/greetings.yml
@@ -0,0 +1,13 @@
+name: Greetings
+
+on: [ pull_request, issues ]
+
+jobs:
+ greeting:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/first-interaction@v1
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-message: 'Message that will be displayed on users'' first issue'
+ pr-message: 'Message that will be displayed on users'' first pr'
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
new file mode 100644
index 00000000..fa826a2b
--- /dev/null
+++ b/.github/workflows/linter.yml
@@ -0,0 +1,52 @@
+---
+###########################
+###########################
+## Linter GitHub Actions ##
+###########################
+###########################
+name: Lint Code Base
+
+#
+# Documentation:
+# https://help.github.com/en/articles/workflow-syntax-for-github-actions
+#
+
+#############################
+# Start the job on all push #
+#############################
+on:
+ push:
+ branches-ignore: [master]
+ # Remove the line above to run when pushing to master
+ pull_request:
+ branches: [master]
+
+###############
+# Set the Job #
+###############
+jobs:
+ build:
+ # Name the Job
+ name: Lint Code Base
+ # Set the agent to run on
+ runs-on: ubuntu-latest
+
+ ##################
+ # Load all steps #
+ ##################
+ steps:
+ ##########################
+ # Checkout the code base #
+ ##########################
+ - name: Checkout Code
+ uses: actions/checkout@v3.1.0
+
+ ################################
+ # Run Linter against code base #
+ ################################
+ - name: Lint Code Base
+ uses: github/super-linter@v3
+ env:
+ VALIDATE_ALL_CODEBASE: false
+ DEFAULT_BRANCH: master
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml
new file mode 100644
index 00000000..682c754b
--- /dev/null
+++ b/.github/workflows/lock.yml
@@ -0,0 +1,23 @@
+name: Lock Closed
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ lock:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dessant/lock-threads@v2
+ with:
+ github-token: '${{ github.token }}'
+ issue-lock-inactive-days: 14
+ issue-lock-comment: |-
+ This issue has been automatically locked since there has not been any
+ recent activity after it was closed. Please open a new issue for
+ related bugs.
+ pr-lock-inactive-days: 14
+ pr-lock-comment: |-
+ This pull request has been automatically locked since there has not
+ been any recent activity after it was closed. Please open a new
+ issue for related bugs.
\ No newline at end of file
diff --git a/.github/workflows/profile-stack.yml b/.github/workflows/profile-stack.yml
new file mode 100644
index 00000000..5240458d
--- /dev/null
+++ b/.github/workflows/profile-stack.yml
@@ -0,0 +1,18 @@
+name: Profile Stack
+
+on:
+ push:
+ branches:
+ - master
+
+jobs:
+ profile_stack:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3.1.0
+ - uses: Matt-Gleich/profile_stack@master
+ with:
+ path: build/ci/techstack.yml
+ badges: true
+ technology_emoji: ๐จ๐ปโ๐ป
+ project_emoji: โจ
\ No newline at end of file
diff --git a/.github/workflows/release-notes-preview.yml b/.github/workflows/release-notes-preview.yml
new file mode 100644
index 00000000..682ea525
--- /dev/null
+++ b/.github/workflows/release-notes-preview.yml
@@ -0,0 +1,21 @@
+name: Release Notes Preview
+
+on:
+ pull_request:
+ branches: [ master ]
+ issue_comment:
+ types: [ edited ]
+
+jobs:
+ preview:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3.1.0
+ - run: |
+ git fetch --prune --unshallow --tags
+ - uses: snyk/release-notes-preview@v1.6.2
+ with:
+ releaseBranch: master
+ env:
+ GITHUB_PR_USERNAME: ${{ github.actor }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..a4d10c1c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,35 @@
+name: Go Releaser
+
+on:
+ pull_request:
+ push:
+
+jobs:
+ goreleaser:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3.1.0
+ with:
+ fetch-depth: 0
+ - name: Set up Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: 1.15
+ - name: Checkout submodules
+ uses: textbook/git-checkout-submodule-action@master
+ with:
+ remote: true
+# - uses: actions/cache@v2
+# with:
+# path: ~/go/pkg/mod
+# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+# restore-keys: |
+# ${{ runner.os }}-go-
+ - name: Run GoReleaser
+ uses: goreleaser/goreleaser-action@v2
+ with:
+ version: latest
+ args: release --rm-dist
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/report-card.yml b/.github/workflows/report-card.yml
new file mode 100644
index 00000000..df37dfb5
--- /dev/null
+++ b/.github/workflows/report-card.yml
@@ -0,0 +1,12 @@
+name: Report Card
+
+on:
+ push:
+ branches:
+ - master
+jobs:
+ report_card:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Go report card
+ uses: creekorful/goreportcard-action@v1.0
diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml
new file mode 100644
index 00000000..e3e1191a
--- /dev/null
+++ b/.github/workflows/reviewdog.yml
@@ -0,0 +1,18 @@
+name: reviewdog
+on: [pull_request]
+jobs:
+ reviewdog:
+ name: reviewdog
+ runs-on: ubuntu-latest
+ steps:
+ # ...
+ - uses: reviewdog/action-setup@v1
+ with:
+ reviewdog_version: latest # Optional. [latest,nightly,v.X.Y.Z]
+ - name: Run reviewdog
+ env:
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ reviewdog -reporter=github-pr-check -runners=golint,govet
+ # or
+ reviewdog -reporter=github-pr-review -runners=golint,govet
\ No newline at end of file
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 00000000..efa5572d
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,29 @@
+name: Close Stale
+
+on:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ stale:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/stale@v3
+ with:
+ repo-token: '${{ github.token }}'
+
+ stale-issue-message: |-
+ This issue is stale because it has been open for 14 days with no
+ activity. It will automatically close after 7 more days of inactivity.
+ stale-issue-label: 'kind/stale'
+ exempt-issue-labels: 'bug,enhancement'
+
+ stale-pr-message: |-
+ This Pull Request is stale because it has been open for 14 days with
+ no activity. It will automatically close after 7 more days of
+ inactivity.
+ stale-pr-label: 'kind/stale'
+ exempt-pr-labels: 'bug,enhancement'
+
+ days-before-stale: 14
+ days-before-close: 7
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..3edbebdc
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,30 @@
+name: Test
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ strategy:
+ matrix:
+ go-version: [1.14.x, 1.15.x]
+ os: [ubuntu-latest]
+ runs-on: ${{ matrix.os }}
+ steps:
+ - name: Install Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go-version }}
+ - name: Checkout code
+ uses: actions/checkout@v3.1.0
+ - name: Checkout submodules
+ uses: textbook/git-checkout-submodule-action@master
+ with:
+ remote: true
+# - uses: actions/cache@v2
+# with:
+# path: ~/go/pkg/mod
+# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+# restore-keys: |
+# ${{ runner.os }}-go-
+ - name: Test
+ run: go test ./...
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f5803673..fa924f6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,4 +18,5 @@
.glide/
# Dependency directories (remove the comment below to include it)
-# vendor/
+vendor/
+.go/cache/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..08af004a
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "third_party/nuclio"]
+ path = third_party/nuclio
+ url = https://github.com/Slahser/nuclio
diff --git a/.golangci.yml b/.golangci.yml
new file mode 100644
index 00000000..44905643
--- /dev/null
+++ b/.golangci.yml
@@ -0,0 +1,48 @@
+linters:
+ disable-all: true
+ enable:
+ - deadcode
+ - goconst
+ - gofmt
+ - golint
+ - gosimple
+ - ineffassign
+ - interfacer
+ - misspell
+ - staticcheck
+ - unconvert
+ - varcheck
+ - vet
+ - vetshadow
+ - errcheck
+ - govet
+ - structcheck
+ - typecheck
+
+run:
+
+ # timeout for analysis
+ timeout: 5m
+
+ skip-dirs:
+ - docs
+
+issues:
+
+ # List of regexps of issue texts to exclude
+ exclude:
+ - "comment on"
+ - "error should be the last"
+ - "should have comment"
+
+ exclude-rules:
+
+ # Auto generated files for kubernetes
+ - path: pkg/platform/kube/client
+ linters:
+ - errcheck
+
+ # list of excluded linters applied on test files
+ - path: _test\.go
+ linters:
+ - goconst
\ No newline at end of file
diff --git a/.goreleaser.yml b/.goreleaser.yml
new file mode 100644
index 00000000..53ac28e9
--- /dev/null
+++ b/.goreleaser.yml
@@ -0,0 +1,76 @@
+env:
+ - GO111MODULE=on
+ - CGO_ENABLED=0
+# This is an example goreleaser.yaml file with some sane defaults.
+# Make sure to check the documentation at http://goreleaser.com
+before:
+ hooks:
+ # you may remove this if you don't use vgo
+ - go mod download
+builds:
+ - id: "ttctl"
+ binary: ttctl
+ main: cmd/ttctl/main.go
+ ldflags:
+ - -s -w -X github.com/Slahser/coup-de-grace/pkg/version.gitVersion={{ .Version }} -X github.com/Slahser/coup-de-grace/pkg/version.gitCommit={{ .ShortCommit }} -X github.com/Slahser/coup-de-grace/pkg/version.buildDate={{ .Date }}
+ goos:
+ - linux
+ - darwin
+ goarch:
+ - 386
+ - amd64
+ - arm
+ - ppc64le
+ - s390x
+archives:
+ - id: ttctl-tarball
+ builds:
+ - ttctl
+ replacements:
+ 386: i386
+ amd64: x86_64
+ format: tar.gz
+ - id: binaries
+ builds:
+ - manager
+ - ttctl
+ replacements:
+ 386: i386
+ amd64: x86_64
+ format: binary
+brews:
+ - name: ttctl
+ tap:
+ owner: Slahser
+ name: homebrew-tap
+ commit_author:
+ name: ttreleasebot
+ email: skyslahser@gmail.com
+ skip_upload: auto
+ folder: Formula
+ homepage: https://slahser.com
+ description: Interact with KUTTL via the kubectl plugin
+ dependencies:
+ -
+ install: |
+ bin.install "ttctl"
+checksum:
+ name_template: "checksums.txt"
+snapshot:
+ name_template: "{{ .Tag }}-next"
+
+release:
+ github:
+ owner: Slahser
+ name: ttctl
+ draft: false
+ prerelease: auto
+ name_template: "{{.ProjectName}}-v{{.Version}}"
+ disable: false
+
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - "^docs:"
+ - "^test:"
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..150aad61
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,11 @@
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: check-byte-order-marker
+ - repo: https://github.com/dnephin/pre-commit-golang
+ rev: master
+ hooks:
+ - id: go-mod-tidy
+ - id: go-imports
+ - id: go-fmt
\ No newline at end of file
diff --git a/.run/(kube) nuctl test.run.xml b/.run/(kube) nuctl test.run.xml
new file mode 100644
index 00000000..1080cb61
--- /dev/null
+++ b/.run/(kube) nuctl test.run.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..0968933f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,57 @@
+# syntax = docker/dockerfile:experimental
+FROM golang:1.15-alpine AS build_base
+
+RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
+RUN apk add --no-cache ca-certificates upx git tzdata libc6-compat make build-base
+RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+RUN echo "Asia/Shanghai" > /etc/timezone
+
+ENV TZ=Asia/Shanghai
+ENV GOPROXY https://goproxy.cn,https://mirrors.aliyun.com/goproxy,direct
+ENV GO111MODULE on
+
+ARG GITLAB_LOGIN=""
+ARG GITLAB_TOKEN=""
+
+RUN echo "machine gitlab.com login ${GITLAB_LOGIN} password ${GITLAB_TOKEN}" > /root/.netrc
+RUN chmod 600 /root/.netrc
+
+WORKDIR /src
+
+#ENV CGO_ENABLED=0
+COPY go.mod .
+COPY go.sum .
+
+RUN go mod download -x
+RUN go get github.com/go-delve/delve/cmd/dlv
+
+COPY . .
+
+RUN --mount=type=cache,target=/root/.cache/go-build \
+ GOOS=linux GOARCH=amd64 \
+# ๆฅๅธธdebug ไฟ็ๆญค่ก
+# go build -gcflags "all=-N -l" \
+# ็บฟไธไผๅไปฃ็ ,ไฟ็ๆญค่ก
+ go build -ldflags="-s -w" \
+ -o ./out/ttapp ./cmd/apiserver
+#RUN upx --best ./out/ttapp -o ./out/ttapp_min
+
+FROM build_base AS gotest
+RUN --mount=type=cache,target=/root/.cache/go-build \
+ go test -v
+#RUN go test -v
+
+#FROM scratch AS bin_base
+FROM alpine:20200917 AS bin_base
+
+COPY --from=build_base /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+COPY --from=build_base /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+COPY --from=build_base /src/out/ttapp /ttapp
+COPY --from=build_base /go/bin/dlv /dlv
+
+EXPOSE 8080 8888
+
+#็บฟไธไผๅไปฃ็ ,ไฟ็ๆญค่ก
+CMD ["/ttapp"]
+#ๆฅๅธธdebug ไฟ็ๆญค่ก
+#CMD ["/dlv", "--listen=:8888", "--headless=true", "--api-version=2", "--log","exec", "/ttapp"]
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 76a4e8ef..d21e261f 100644
--- a/Makefile
+++ b/Makefile
@@ -1 +1,260 @@
-# note: call scripts from /scripts
\ No newline at end of file
+# Copyright 2016 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# The binaries to build (just the basenames).
+BINS := myapp-1 myapp-2
+
+# Where to push the docker image.
+REGISTRY ?= example.com
+
+# This version-strategy uses git tags to set the version string
+VERSION ?= $(shell git describe --tags --always --dirty)
+#
+# This version-strategy uses a manual value to set the version string
+#VERSION ?= 1.2.3
+
+###
+### These variables should not need tweaking.
+###
+
+SRC_DIRS := cmd pkg # directories which hold app source (not vendored)
+
+ALL_PLATFORMS := linux/amd64 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64
+
+# Used internally. Users should pass GOOS and/or GOARCH.
+OS := $(if $(GOOS),$(GOOS),$(shell go env GOOS))
+ARCH := $(if $(GOARCH),$(GOARCH),$(shell go env GOARCH))
+
+BASEIMAGE ?= gcr.io/distroless/static
+
+TAG := $(VERSION)__$(OS)_$(ARCH)
+
+BUILD_IMAGE ?= golang:1.14-alpine
+
+BIN_EXTENSION :=
+ifeq ($(OS), windows)
+ BIN_EXTENSION := .exe
+endif
+
+# If you want to build all binaries, see the 'all-build' rule.
+# If you want to build all containers, see the 'all-container' rule.
+# If you want to build AND push all containers, see the 'all-push' rule.
+all: # @HELP builds binaries for one platform ($OS/$ARCH)
+all: build
+
+# For the following OS/ARCH expansions, we transform OS/ARCH into OS_ARCH
+# because make pattern rules don't match with embedded '/' characters.
+
+build-%:
+ @$(MAKE) build \
+ --no-print-directory \
+ GOOS=$(firstword $(subst _, ,$*)) \
+ GOARCH=$(lastword $(subst _, ,$*))
+
+container-%:
+ @$(MAKE) container \
+ --no-print-directory \
+ GOOS=$(firstword $(subst _, ,$*)) \
+ GOARCH=$(lastword $(subst _, ,$*))
+
+push-%:
+ @$(MAKE) push \
+ --no-print-directory \
+ GOOS=$(firstword $(subst _, ,$*)) \
+ GOARCH=$(lastword $(subst _, ,$*))
+
+all-build: # @HELP builds binaries for all platforms
+all-build: $(addprefix build-, $(subst /,_, $(ALL_PLATFORMS)))
+
+all-container: # @HELP builds containers for all platforms
+all-container: $(addprefix container-, $(subst /,_, $(ALL_PLATFORMS)))
+
+all-push: # @HELP pushes containers for all platforms to the defined registry
+all-push: $(addprefix push-, $(subst /,_, $(ALL_PLATFORMS)))
+
+# The following structure defeats Go's (intentional) behavior to always touch
+# result files, even if they have not changed. This will still run `go` but
+# will not trigger further work if nothing has actually changed.
+OUTBINS = $(foreach bin,$(BINS),bin/$(OS)_$(ARCH)/$(bin)$(BIN_EXTENSION))
+
+build: $(OUTBINS)
+
+# Directories that we need created to build/test.
+BUILD_DIRS := bin/$(OS)_$(ARCH) \
+ .go/bin/$(OS)_$(ARCH) \
+ .go/cache
+
+# Each outbin target is just a facade for the respective stampfile target.
+# This `eval` establishes the dependencies for each.
+$(foreach outbin,$(OUTBINS),$(eval \
+ $(outbin): .go/$(outbin).stamp \
+))
+# This is the target definition for all outbins.
+$(OUTBINS):
+ @true
+
+# Each stampfile target can reference an $(OUTBIN) variable.
+$(foreach outbin,$(OUTBINS),$(eval $(strip \
+ .go/$(outbin).stamp: OUTBIN = $(outbin) \
+)))
+# This is the target definition for all stampfiles.
+# This will build the binary under ./.go and update the real binary iff needed.
+STAMPS = $(foreach outbin,$(OUTBINS),.go/$(outbin).stamp)
+.PHONY: $(STAMPS)
+$(STAMPS): go-build
+ @echo "binary: $(OUTBIN)"
+ @if ! cmp -s .go/$(OUTBIN) $(OUTBIN); then \
+ mv .go/$(OUTBIN) $(OUTBIN); \
+ date >$@; \
+ fi
+
+# This runs the actual `go build` which updates all binaries.
+go-build: $(BUILD_DIRS)
+ @echo
+ @echo "building for $(OS)/$(ARCH)"
+ @docker run \
+ -i \
+ --rm \
+ -u $$(id -u):$$(id -g) \
+ -v $$(pwd):/src \
+ -w /src \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
+ -v $$(pwd)/.go/cache:/.cache \
+ --env HTTP_PROXY=$(HTTP_PROXY) \
+ --env HTTPS_PROXY=$(HTTPS_PROXY) \
+ $(BUILD_IMAGE) \
+ /bin/sh -c " \
+ ARCH=$(ARCH) \
+ OS=$(OS) \
+ VERSION=$(VERSION) \
+ ./build/build.sh \
+ "
+
+# Example: make shell CMD="-c 'date > datefile'"
+shell: # @HELP launches a shell in the containerized build environment
+shell: $(BUILD_DIRS)
+ @echo "launching a shell in the containerized build environment"
+ @docker run \
+ -ti \
+ --rm \
+ -u $$(id -u):$$(id -g) \
+ -v $$(pwd):/src \
+ -w /src \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
+ -v $$(pwd)/.go/cache:/.cache \
+ --env HTTP_PROXY=$(HTTP_PROXY) \
+ --env HTTPS_PROXY=$(HTTPS_PROXY) \
+ $(BUILD_IMAGE) \
+ /bin/sh $(CMD)
+
+CONTAINER_DOTFILES = $(foreach bin,$(BINS),.container-$(subst /,_,$(REGISTRY)/$(bin))-$(TAG))
+
+container containers: # @HELP builds containers for one platform ($OS/$ARCH)
+container containers: $(CONTAINER_DOTFILES)
+ @for bin in $(BINS); do \
+ echo "container: $(REGISTRY)/$$bin:$(TAG)"; \
+ done
+
+# Each container-dotfile target can reference a $(BIN) variable.
+# This is done in 2 steps to enable target-specific variables.
+$(foreach bin,$(BINS),$(eval $(strip \
+ .container-$(subst /,_,$(REGISTRY)/$(bin))-$(TAG): BIN = $(bin) \
+)))
+$(foreach bin,$(BINS),$(eval \
+ .container-$(subst /,_,$(REGISTRY)/$(bin))-$(TAG): bin/$(OS)_$(ARCH)/$(bin) Dockerfile.in \
+))
+# This is the target definition for all container-dotfiles.
+# These are used to track build state in hidden files.
+$(CONTAINER_DOTFILES):
+ @sed \
+ -e 's|{ARG_BIN}|$(BIN)|g' \
+ -e 's|{ARG_ARCH}|$(ARCH)|g' \
+ -e 's|{ARG_OS}|$(OS)|g' \
+ -e 's|{ARG_FROM}|$(BASEIMAGE)|g' \
+ Dockerfile.in > .dockerfile-$(BIN)-$(OS)_$(ARCH)
+ @docker build -t $(REGISTRY)/$(BIN):$(TAG) -f .dockerfile-$(BIN)-$(OS)_$(ARCH) .
+ @docker images -q $(REGISTRY)/$(BIN):$(TAG) > $@
+ @echo
+
+push: # @HELP pushes the container for one platform ($OS/$ARCH) to the defined registry
+push: $(CONTAINER_DOTFILES)
+ @for bin in $(BINS); do \
+ docker push $(REGISTRY)/$$bin:$(TAG); \
+ done
+
+manifest-list: # @HELP builds a manifest list of containers for all platforms
+manifest-list: all-push
+ @for bin in $(BINS); do \
+ platforms=$$(echo $(ALL_PLATFORMS) | sed 's/ /,/g'); \
+ manifest-tool \
+ --username=oauth2accesstoken \
+ --password=$$(gcloud auth print-access-token) \
+ push from-args \
+ --platforms "$$platforms" \
+ --template $(REGISTRY)/$$bin:$(VERSION)__OS_ARCH \
+ --target $(REGISTRY)/$$bin:$(VERSION)
+
+version: # @HELP outputs the version string
+version:
+ @echo $(VERSION)
+
+test: # @HELP runs tests, as defined in ./build/test.sh
+test: $(BUILD_DIRS)
+ @docker run \
+ -i \
+ --rm \
+ -u $$(id -u):$$(id -g) \
+ -v $$(pwd):/src \
+ -w /src \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin \
+ -v $$(pwd)/.go/bin/$(OS)_$(ARCH):/go/bin/$(OS)_$(ARCH) \
+ -v $$(pwd)/.go/cache:/.cache \
+ --env HTTP_PROXY=$(HTTP_PROXY) \
+ --env HTTPS_PROXY=$(HTTPS_PROXY) \
+ $(BUILD_IMAGE) \
+ /bin/sh -c " \
+ ARCH=$(ARCH) \
+ OS=$(OS) \
+ VERSION=$(VERSION) \
+ ./build/test.sh $(SRC_DIRS) \
+ "
+
+$(BUILD_DIRS):
+ @mkdir -p $@
+
+clean: # @HELP removes built binaries and temporary files
+clean: container-clean bin-clean
+
+container-clean:
+ rm -rf .container-* .dockerfile-*
+
+bin-clean:
+ rm -rf .go bin
+
+help: # @HELP prints this message
+help:
+ @echo "VARIABLES:"
+ @echo " BINS = $(BINS)"
+ @echo " OS = $(OS)"
+ @echo " ARCH = $(ARCH)"
+ @echo " REGISTRY = $(REGISTRY)"
+ @echo
+ @echo "TARGETS:"
+ @grep -E '^.*: *# *@HELP' $(MAKEFILE_LIST) \
+ | awk ' \
+ BEGIN {FS = ": *# *@HELP"}; \
+ { printf " %-30s %s\n", $$1, $$2 }; \
+ '
diff --git a/README.md b/README.md
index 00f23740..76204e2b 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Standard Go Project Layout
+
+
Translations:
* [ไธญๆๆๆกฃ](README_zh.md)
@@ -185,8 +187,15 @@ Don't confuse the project level `/src` directory with the `/src` directory Go us
[](http://godoc.org/github.com/golang-standards/project-layout)
[](https://pkg.go.dev/github.com/golang-standards/project-layout)
[](https://github.com/golang-standards/project-layout/releases/latest)
+[](https://github.com/marketplace/actions/super-linter)
+[](https://gitpod.io/from-referrer/)
## Notes
A more opinionated project template with sample/reusable configs, scripts and code is a WIP.
+
+| ๐จ๐ปโ๐ป **Technology** | โจ **Projects** |
+|-|-|
+| [](https://dart.dev/) | [](https://github.com/fluttercommunity/import_sorter) [](https://github.com/Matt-Gleich/Personal-Site) [](https://github.com/Matt-Gleich/auralite-mobile) |
+| [](https://flutter.dev/) | [](https://github.com/Matt-Gleich/Personal-Site) [](https://github.com/Matt-Gleich/auralite-mobile) |
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..034e8480
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,21 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 5.1.x | :white_check_mark: |
+| 5.0.x | :x: |
+| 4.0.x | :white_check_mark: |
+| < 4.0 | :x: |
+
+## Reporting a Vulnerability
+
+Use this section to tell people how to report a vulnerability.
+
+Tell them where to go, how often they can expect to get an update on a
+reported vulnerability, what to expect if the vulnerability is accepted or
+declined, etc.
diff --git a/assets/nyancat.txt b/assets/nyancat.txt
new file mode 100644
index 00000000..2ae0310b
--- /dev/null
+++ b/assets/nyancat.txt
@@ -0,0 +1,32 @@
+
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+{{.AnsiColor.Red}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโ
+{{.AnsiColor.Red}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโ
+{{.AnsiColor.BrightRed}}โโโโ{{.AnsiColor.Red}}โโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ
+{{.AnsiColor.BrightRed}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.Magenta}}โโโโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.BrightBlue}}โโโโโโ
+{{.AnsiColor.BrightRed}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.Magenta}}โโโโโโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโ
+{{.AnsiColor.BrightYellow}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightRed}}โโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Magenta}}โโโโโโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโ
+{{.AnsiColor.BrightYellow}}โโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightYellow}}โโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโโโโโโโ{{.AnsiColor.White}}โโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโ
+{{.AnsiColor.BrightYellow}}โโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightYellow}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโ
+{{.AnsiColor.BrightGreen}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightYellow}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโโโโโโโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ
+{{.AnsiColor.BrightGreen}}โโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.White}}โโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.BrightYellow}}โโ{{.AnsiColor.White}}โโโโโโโโโโ{{.AnsiColor.BrightYellow}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ
+{{.AnsiColor.BrightGreen}}โโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ
+{{.AnsiColor.Blue}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightGreen}}โโโโโโโโ{{.AnsiColor.Black}}โโโโโโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Magenta}}โโโโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโ{{.AnsiColor.Magenta}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ
+{{.AnsiColor.Blue}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโโโโโโโโโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.Blue}}โโโโ{{.AnsiColor.Blue}}โโโโโโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Magenta}}โโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโโโโโโโโโโโโโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโโโ{{.AnsiColor.Black}}โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.White}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโโโ{{.AnsiColor.White}}โโโโ{{.AnsiColor.Black}}โโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ
+{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโโโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโโโ{{.AnsiColor.BrightBlue}}โโโโ{{.AnsiColor.Black}}โโโโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ{{.AnsiColor.Black}}โโโโโโ{{.AnsiColor.BrightBlue}}โโโโ{{.AnsiColor.Black}}โโโโโโ{{.AnsiColor.BrightBlue}}โโโโโโโโโโโโ
+โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+{{ .AnsiColor.Default }}
+GoVersion: {{ .GoVersion }}
+GOOS: {{ .GOOS }}
+GOARCH: {{ .GOARCH }}
+NumCPU: {{ .NumCPU }}
+GOPATH: {{ .GOPATH }}
+GOROOT: {{ .GOROOT }}
+Compiler: {{ .Compiler }}
+ENV: {{ .Env "GOPATH" }}
+Now: {{ .Now "Monday, 2 Jan 2006" }}
diff --git a/build/build.sh b/build/build.sh
new file mode 100755
index 00000000..67d57c98
--- /dev/null
+++ b/build/build.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# Copyright 2016 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+if [ -z "${OS:-}" ]; then
+ echo "OS must be set"
+ exit 1
+fi
+if [ -z "${ARCH:-}" ]; then
+ echo "ARCH must be set"
+ exit 1
+fi
+if [ -z "${VERSION:-}" ]; then
+ echo "VERSION must be set"
+ exit 1
+fi
+
+export CGO_ENABLED=0
+export GOARCH="${ARCH}"
+export GOOS="${OS}"
+export GO111MODULE=on
+export GOFLAGS="-mod=vendor"
+
+go install \
+ -installsuffix "static" \
+ -ldflags "-X $(go list -m)/pkg/version.Version=${VERSION}" \
+ ./...
diff --git a/build/ci/techstack.yml b/build/ci/techstack.yml
new file mode 100644
index 00000000..eada08d6
--- /dev/null
+++ b/build/ci/techstack.yml
@@ -0,0 +1,17 @@
+- name: Dart
+ logo: dart
+ url: https://dart.dev/
+ color: 52C0F2
+ projects:
+ - https://github.com/fluttercommunity/import_sorter
+ - https://github.com/Matt-Gleich/Personal-Site
+ - url: https://github.com/Matt-Gleich/auralite-mobile
+ wip: true
+- name: Flutter
+ logo: flutter
+ url: https://flutter.dev/
+ color: 52C0F2
+ projects:
+ - https://github.com/Matt-Gleich/Personal-Site
+ - url: https://github.com/Matt-Gleich/auralite-mobile
+ wip: true
\ No newline at end of file
diff --git a/build/pre-commit.just b/build/pre-commit.just
new file mode 100644
index 00000000..fd1d2825
--- /dev/null
+++ b/build/pre-commit.just
@@ -0,0 +1,59 @@
+# use with https://github.com/casey/just
+
+# Example combining just + pre-commit
+# pre-commit: https://pre-commit.com/
+# > A framework for managing and maintaining
+# > multi-language pre-commit hooks.
+
+# pre-commit brings about encapsulation of your
+# most common repo scripting tasks. It is perfectly
+# usable without actually setting up precommit hooks.
+# If you chose to, this justfiles includes shorthands
+# for git commit and amend to keep pre-commit out of
+# the way when in flow on a feature branch.
+
+# uses: https://github.com/tekwizely/pre-commit-golang
+# uses: https://github.com/prettier/prettier (pre-commit hook)
+# configures: https://www.git-town.com/ (setup receipt)
+
+# fix auto-fixable lint issues in staged files
+fix:
+ pre-commit run go-returns # fixes all Go lint issues
+ pre-commit run prettier # fixes all Markdown (& other) lint issues
+
+# lint most common issues in - or due - to staged files
+lint:
+ pre-commit run go-vet-mod || true # runs go vet
+ pre-commit run go-lint || true # runs golint
+ pre-commit run go-critic || true # runs gocritic
+
+# lint all issues in - or due - to staged files:
+lint-all:
+ pre-commit run golangci-lint-mod || true # runs golangci-lint
+
+# run tests in - or due - to staged files
+test:
+ pre-commit run go-test-mod || true # runs go test
+
+# commit skipping pre-commit hooks
+commit m:
+ git commit --no-verify -m "{{m}}"
+
+# amend skipping pre-commit hooks
+amend:
+ git commit --amend --no-verify
+
+# install/update code automation (prettier, pre-commit, goreturns, lintpack, gocritic, golangci-lint)
+install:
+ npm i -g prettier
+ curl https://pre-commit.com/install-local.py | python3 -
+ go get github.com/sqs/goreturns
+ go get github.com/go-lintpack/lintpack/...
+ go get github.com/go-critic/go-critic/...
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.27.0
+
+# setup/update pre-commit hooks (optional)
+setup:
+ pre-commit install --install-hooks # uninstall: `pre-commit uninstall`
+ git config git-town.code-hosting-driver gitea # setup git-town with gitea
+ git config git-town.code-hosting-origin-hostname gitea.example.org # setup git-town origin hostname
diff --git a/build/test.sh b/build/test.sh
new file mode 100755
index 00000000..b1d144b4
--- /dev/null
+++ b/build/test.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# Copyright 2016 The Kubernetes Authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+export CGO_ENABLED=0
+export GO111MODULE=on
+export GOFLAGS="-mod=vendor"
+
+TARGETS=$(for d in "$@"; do echo ./$d/...; done)
+
+echo "Running tests:"
+go test -installsuffix "static" ${TARGETS}
+echo
+
+echo -n "Checking gofmt: "
+ERRS=$(find "$@" -type f -name \*.go | xargs gofmt -l 2>&1 || true)
+if [ -n "${ERRS}" ]; then
+ echo "FAIL - the following files need to be gofmt'ed:"
+ for e in ${ERRS}; do
+ echo " $e"
+ done
+ echo
+ exit 1
+fi
+echo "PASS"
+echo
+
+echo -n "Checking go vet: "
+ERRS=$(go vet ${TARGETS} 2>&1 || true)
+if [ -n "${ERRS}" ]; then
+ echo "FAIL"
+ echo "${ERRS}"
+ echo
+ exit 1
+fi
+echo "PASS"
+echo
diff --git a/cloudbuild.yaml b/cloudbuild.yaml
new file mode 100644
index 00000000..4c66bd7a
--- /dev/null
+++ b/cloudbuild.yaml
@@ -0,0 +1,12 @@
+# https://console.cloud.google.com/cloud-build/builds?project=thockin-gce-public&authuser=1
+steps:
+ - name: gcr.io/cloud-builders/docker
+ entrypoint: make
+ env:
+ - GOOS="fake" # the Makefile looks for these,
+ - GOARCH="fake" # even if it won't need them
+ - VERSION=$SHORT_SHA
+ args:
+ - test
+ - all-container
+timeout: 300s
diff --git a/cmd/_your_app_/.keep b/cmd/_your_app_/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/cmd/edgeserver/config.toml b/cmd/edgeserver/config.toml
new file mode 100644
index 00000000..79ac78fb
--- /dev/null
+++ b/cmd/edgeserver/config.toml
@@ -0,0 +1,13 @@
+env = "dev" #ๅฟ
้
+org = "slahser"#ๅฟ
้
+project = "ttproj"#ๅฟ
้
+
+
+
+
+
+
+
+
+
+
diff --git a/cmd/edgeserver/playground.go b/cmd/edgeserver/playground.go
new file mode 100644
index 00000000..a1107104
--- /dev/null
+++ b/cmd/edgeserver/playground.go
@@ -0,0 +1,56 @@
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+ "go.uber.org/zap"
+
+ "github.com/Slahser/coup-de-grace/pkg/edgeserver"
+)
+
+func main() {
+ server := edgeserver.Init()
+
+ server.HTTPGet("/tt/:name", TemplateHTTPGetHandlerFunc)
+ server.HTTPPost("/cleanDir", TemplateHTTPPostHandlerFunc)
+ server.WSGet("/ping", TemplateWSGetHandlerFunc)
+
+ server.Start()
+}
+
+//path /user/:name
+var TemplateHTTPGetHandlerFunc gin.HandlerFunc = func(context *gin.Context) {
+ name := context.Param("name")
+ zap.S().Info("name is : " + name)
+ context.String(http.StatusOK, "Hello %s", name)
+}
+
+//body name=manu&message=this_is_great
+var TemplateHTTPPostHandlerFunc gin.HandlerFunc = func(context *gin.Context) {
+ //POSIX
+ //sh.Exec(context.Param("dir"))
+ name := context.PostForm("name")
+ message := context.PostForm("message")
+ zap.S().Debug("name is : " + name)
+ context.JSON(http.StatusOK, name+message)
+}
+
+//path /ping
+var TemplateWSGetHandlerFunc gin.HandlerFunc = func(context *gin.Context) {
+ wsConn := edgeserver.GetWSConn(context)
+ for {
+ mt, message, err := wsConn.ReadMessage()
+ if err != nil {
+ break
+ }
+ if string(message) == "ping" {
+ message = []byte("pong")
+ }
+ zap.S().Info("websocket write back pong")
+ err = wsConn.WriteMessage(mt, message)
+ if err != nil {
+ break
+ }
+ }
+}
diff --git a/cmd/exercise_golang/goproxy_selfhost/goproxy_selfhost.go b/cmd/exercise_golang/goproxy_selfhost/goproxy_selfhost.go
new file mode 100644
index 00000000..dc73f985
--- /dev/null
+++ b/cmd/exercise_golang/goproxy_selfhost/goproxy_selfhost.go
@@ -0,0 +1,18 @@
+package goproxy_selfhost
+
+import (
+ "github.com/goproxy/goproxy"
+ "net/http"
+ "os"
+)
+
+func SelfHostGoProxy() {
+ g := goproxy.New()
+ g.GoBinEnv = append(
+ os.Environ(),
+ "GOPROXY=https://goproxy_selfhost.cn,direct", // ไฝฟ็จ goproxy_selfhost.cn ไฝไธบไธๆธธไปฃ็
+ "GOPRIVATE=git.example.com", // ่งฃๅณ็งๆๆจกๅ็ๆๅ้ฎ้ข๏ผๆฏๅฆๅฏไปฅ้
็ฝฎๆๅ
ฌๅธๅ
้จ็ไปฃ็ ๆบ๏ผ
+ )
+ g.ProxiedSUMDBs = []string{"sum.golang.org https://goproxy_selfhost.cn/sumdb/sum.golang.org"} // ไปฃ็้ป่ฎค็ๆ ก้ชๅๆฐๆฎๅบ
+ _ = http.ListenAndServe("localhost:10086", g)
+}
diff --git a/cmd/exercise_golang/main.go b/cmd/exercise_golang/main.go
new file mode 100644
index 00000000..0f61b3e0
--- /dev/null
+++ b/cmd/exercise_golang/main.go
@@ -0,0 +1,54 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "net/http"
+ _ "net/http/pprof"
+ "os"
+ "time"
+
+ "github.com/Slahser/coup-de-grace/internal/app/tt_practice"
+ "github.com/dimiro1/banner"
+ _ "github.com/dimiro1/banner/autoload"
+ "github.com/felixge/fgprof"
+)
+
+func main() {
+
+ http.DefaultServeMux.Handle("/debug/fgprof", fgprof.Handler())
+ go func() {
+ log.Println(http.ListenAndServe(":6060", nil))
+ }()
+
+ nyanFilePath := "assets/nyancat.txt"
+ nyanBuf, err := ioutil.ReadFile(nyanFilePath)
+ if err != nil {
+ _, _ = fmt.Fprintf(os.Stderr, "File Error: %s\n", err)
+ // panic(err.Error())
+ }
+
+ isEnabled := true
+ isColorEnabled := true
+ banner.Init(os.Stdout, isEnabled, isColorEnabled, bytes.NewBuffer(nyanBuf))
+
+ //=====
+ start := time.Now()
+
+ //practice
+ tt_practice.Tt1()
+ tt_practice.Tt2()
+ tt_practice.Tt3()
+ tt_practice.Tt4()
+ tt_practice.Tt5()
+ tt_practice.Tt6()
+
+ print(tt_practice.TtErrorHandle())
+
+ //=====
+ end := time.Now()
+ cost := end.Sub(start)
+ fmt.Printf("total cost is %s\n", cost)
+}
diff --git a/cmd/exercise_k8s/main.go b/cmd/exercise_k8s/main.go
new file mode 100644
index 00000000..d3f23055
--- /dev/null
+++ b/cmd/exercise_k8s/main.go
@@ -0,0 +1,100 @@
+package main
+
+import (
+ "fmt"
+ "strconv"
+ "time"
+
+ nucliowrapper "github.com/Slahser/coup-de-grace/internal/pkg/nuclio_wrapper"
+
+ "github.com/Slahser/coup-de-grace/internal/app/helper"
+ traefikwrapper "github.com/Slahser/coup-de-grace/internal/pkg/traefik_wrapper"
+ "github.com/Slahser/coup-de-grace/internal/pkg/traefik_wrapper/traefiksvcfactory"
+ errors "github.com/go-errors/errors"
+ zap "go.uber.org/zap"
+ k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+var ()
+
+func main() {
+
+ //ๅ
จๅฑlogger้
็ฝฎ
+ logger := helper.InitLogger()
+ undo := zap.ReplaceGlobals(logger)
+ defer undo()
+
+ //ttTraefik()
+ ttNuclio()
+
+}
+
+func ttNuclio() {
+
+ funcList, _ := nucliowrapper.Functions().List(k8smetav1.ListOptions{})
+ for i, mw := range funcList.Items {
+ fmt.Println("func" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+ funcEventsList, _ := nucliowrapper.FunctionEvents().List(k8smetav1.ListOptions{})
+ for i, mw := range funcEventsList.Items {
+ fmt.Println("funcEvent" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+ projectsList, _ := nucliowrapper.Projects().List(k8smetav1.ListOptions{})
+ for i, mw := range projectsList.Items {
+ fmt.Println("project" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+}
+
+func ttTraefik() {
+
+ middlewareList, _ := traefikwrapper.Middlewares().List(k8smetav1.ListOptions{})
+ for i, mw := range middlewareList.Items {
+ fmt.Println("mw" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+ routeList, _ := traefikwrapper.IngressRoutes().List(k8smetav1.ListOptions{})
+ for i, mw := range routeList.Items {
+ fmt.Println("route" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+ svcList, _ := traefikwrapper.TraefikServices().List(k8smetav1.ListOptions{})
+ for i, mw := range svcList.Items {
+ fmt.Println("svc" + strconv.Itoa(i) + "=>" + mw.Name)
+ }
+
+ //gen svc self hosted
+ selfHostedSvc, _ := traefiksvcfactory.Create(traefiksvcfactory.SELF_HOSTED, make(map[string]interface{}))
+
+ //gen svc cloud hosted
+ cloudHostedSvc, _ := traefiksvcfactory.Create(traefiksvcfactory.CLOUD_HOSTED, make(map[string]interface{}))
+
+ //gen svc aggr
+ aggrSvc, _ := traefiksvcfactory.Create(traefiksvcfactory.AGGR, make(map[string]interface{}))
+
+ print(selfHostedSvc)
+ print(cloudHostedSvc)
+ print(aggrSvc)
+
+ execedSvc, createErr := traefikwrapper.TraefikServices().Create(cloudHostedSvc)
+ if createErr != nil {
+ zap.S().Error(errors.Errorf("create err %w", createErr))
+ } else {
+ zap.S().Info("created svc " + execedSvc.Name)
+
+ time.Sleep(5 * 1e8)
+
+ if deletedErr := traefikwrapper.TraefikServices().Delete(execedSvc.Name, &k8smetav1.DeleteOptions{
+ TypeMeta: k8smetav1.TypeMeta{
+ Kind: "TraefikService",
+ APIVersion: "traefik.containo.us/v1alpha1",
+ },
+ }); deletedErr != nil {
+ zap.S().Error(errors.Errorf("delete err %w", deletedErr))
+ } else {
+ zap.S().Info("deleted svc " + execedSvc.Name)
+ }
+ }
+}
diff --git a/cmd/exercise_tui/main.go b/cmd/exercise_tui/main.go
new file mode 100644
index 00000000..cb6345ca
--- /dev/null
+++ b/cmd/exercise_tui/main.go
@@ -0,0 +1,179 @@
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+
+ prompt "github.com/c-bata/go-prompt"
+ gosxnotifier "github.com/deckarep/gosx-notifier"
+ banner "github.com/dimiro1/banner"
+ asciigraph "github.com/guptarohit/asciigraph"
+ table "github.com/jedib0t/go-pretty/table"
+ opts "github.com/jpillora/opts"
+)
+
+//go-prompt
+func completer(d prompt.Document) []prompt.Suggest {
+ s := []prompt.Suggest{
+ {Text: "users", Description: "Store the username and age"},
+ {Text: "articles", Description: "Store the article text posted by user"},
+ {Text: "comments", Description: "Store the text commented to articles"},
+ }
+ return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true)
+}
+
+func main() {
+ //banner start
+ nyanFilePath := "assets/nyancat.txt"
+ nyanBuf, err := ioutil.ReadFile(nyanFilePath)
+ if err != nil {
+ _, _ = fmt.Fprintf(os.Stderr, "File Error: %s\n", err)
+ // panic(err.Error())
+ }
+
+ banner.Init(os.Stdout, true, true, bytes.NewBuffer(nyanBuf))
+ //banner stop
+
+ //go-prompt start
+ fmt.Println("go-prompt demo,Please select item.")
+ t := prompt.Input("> ", completer)
+ fmt.Println("You selected " + t)
+ //go-prompt end
+
+ //At a minimum specifiy a message to display to end-user.
+ note := gosxnotifier.NewNotification("tt") //Optionally, set a title
+ note.Title = "tt override!!! ๐ฐ"
+
+ //Optionally, set a subtitle
+ note.Subtitle = "tt subtitle"
+ //Optionally, set a sound from a predefined set.
+ note.Sound = gosxnotifier.Basso
+
+ //Optionally, specifiy a url or bundleid to open should the notification be
+ //clicked.
+ note.Link = "https://www.google.com" //or BundleID like: com.apple.Terminal
+
+ //Optionally, an app icon (10.9+ ONLY)
+ note.AppIcon = "gopher.png"
+
+ //Optionally, a content image (10.9+ ONLY)
+ note.ContentImage = "gopher.png"
+
+ //If necessary, check error
+ if err := note.Push(); err != nil {
+ log.Println("Uh oh!")
+ }
+
+ typicalMap := make(map[string]string)
+ typicalMap["-a"] = "All, append"
+ typicalMap["-b"] = "Buffer,block size, batch"
+ typicalMap["-c"] = "Command, check"
+ typicalMap["-d"] = "Debug, delete, directory"
+ typicalMap["-D"] = "Define"
+ typicalMap["-e"] = "Execute, edit"
+ typicalMap["-f"] = "File, force"
+ typicalMap["-h"] = "Headers, help"
+ typicalMap["-i"] = "Initialize"
+ typicalMap["-I"] = "Include"
+ typicalMap["-k"] = "Keep, kill"
+ typicalMap["-l"] = "List, long, load"
+ typicalMap["-m"] = "Message"
+ typicalMap["-n"] = "Number, not"
+ typicalMap["-o"] = "Output"
+ typicalMap["-p"] = "Port, protocol"
+ typicalMap["-q"] = "Quiet"
+ typicalMap["-r"] = "Recurse, reverse"
+ typicalMap["-s"] = "Silent, subject"
+ typicalMap["-t"] = "Tag"
+ typicalMap["-u"] = "User"
+ typicalMap["-v"] = "Verbose"
+ typicalMap["-V"] = "Version"
+ typicalMap["-w"] = "Width, warning"
+ typicalMap["-x"] = "Enable debugging, extract"
+ typicalMap["-y"] = "Yes"
+ typicalMap["-z"] = "Enable compression"
+
+ //table start
+ rt := table.NewWriter()
+ rt.SetOutputMirror(os.Stdout)
+ rt.AppendHeader(table.Row{"Option", "Typical meaning"})
+ for op, tm := range typicalMap {
+ rt.AppendRow([]interface{}{op, tm})
+ }
+ rt.AppendRow([]interface{}{})
+ rt.Render()
+ //table stop
+
+ //opts start
+ //https://github.com/jpillora/opts ็ธๆฏไนไธ่ฟไธชๆดๅฅฝไธไบ
+ //https://github.com/jessevdk/go-flags
+ c := config{}
+ opts.Parse(&c)
+ log.Printf("%+v", c)
+ //opts stop
+
+ //cobra start most famous
+ //https://github.com/spf13/cobra
+
+ //cobra stop
+
+ //promptui start
+ //https://github.com/manifoldco/promptui
+
+ //promotui stop
+
+ //progressbar start
+ //https://github.com/cheggaaa/pb
+ //https://github.com/vbauerster/mpb
+ //https://github.com/Gosuri/uilive
+ //progressbar stop
+
+ //asciigraph start
+ data := []float64{3, 4, 9, 6, 2, 4, 5, 8, 5, 10, 2, 7, 2, 5, 6}
+ graph := asciigraph.Plot(data)
+
+ fmt.Println(graph)
+ //asciigraph stop
+
+ //color start
+ //https://github.com/fatih/color
+ //color stop
+
+ //web start
+ //https://github.com/gin-Gonic/gin
+ //validate
+ //https://github.com/Go-playground/validator
+ //web stop
+
+ //tool
+ //https://github.com/thoas/Go-funk
+
+ //rest client
+ //https://github.com/h2non/gentleman
+ //https://github.com/Go-resty/resty
+ //deepcopy
+ //https://github.com/ulule/deepcopier
+ //deepcopy
+}
+
+/**
+$ go build -o my-prog
+$ ./my-prog --help
+
+ Usage: my-prog [options]
+
+ Options:
+ --file, -f file to load
+ --lines, -l number of lines to show
+ --help, -h display help
+
+$ ./my-prog -f foo.txt -l 42
+{File:foo.txt Lines:42}
+*/
+type config struct {
+ File string `opts:"help=file to load"`
+ Lines int `opts:"help=number of lines to show"`
+}
diff --git a/cmd/ttctl/app/ttctl.go b/cmd/ttctl/app/ttctl.go
new file mode 100644
index 00000000..ab5d9cd9
--- /dev/null
+++ b/cmd/ttctl/app/ttctl.go
@@ -0,0 +1,24 @@
+package app
+
+import (
+ "github.com/Slahser/coup-de-grace/pkg/ttctl"
+ "net/http"
+ "github.com/inconshreveable/go-update"
+)
+
+func Run() error {
+ return ttctl.NewRootCommandeer().Execute()
+}
+
+func doUpdate(url string) error {
+ resp, err := http.Get(url)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ if err := update.Apply(resp.Body, update.Options{}); err != nil {
+ // error handling
+ }
+ return err
+}
\ No newline at end of file
diff --git a/cmd/ttctl/main.go b/cmd/ttctl/main.go
new file mode 100644
index 00000000..f2bbd812
--- /dev/null
+++ b/cmd/ttctl/main.go
@@ -0,0 +1,21 @@
+package main
+
+import (
+ "os"
+
+ jsoniter "github.com/json-iterator/go"
+
+ "github.com/Slahser/coup-de-grace/cmd/ttctl/app"
+)
+
+var (
+ json = jsoniter.ConfigCompatibleWithStandardLibrary
+)
+
+func main() {
+
+ if err := app.Run(); err != nil {
+ os.Exit(1)
+ }
+ os.Exit(0)
+}
diff --git a/cmd/ttserver/app/ttApiServer.go b/cmd/ttserver/app/ttApiServer.go
new file mode 100644
index 00000000..9feb58e9
--- /dev/null
+++ b/cmd/ttserver/app/ttApiServer.go
@@ -0,0 +1,46 @@
+package app
+
+import (
+ "time"
+
+ "github.com/Slahser/coup-de-grace/pkg/ttserver/path"
+
+ "github.com/Slahser/coup-de-grace/internal/app/helper"
+ endless "github.com/fvbock/endless"
+ gin "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+ "go.uber.org/zap"
+)
+
+var (
+ listeningPort = ":8080"
+ runningMode = gin.DebugMode
+)
+
+func Run() error {
+
+ gin.SetMode(runningMode)
+ router := gin.New()
+ //ๅบ็กไธญ้ดไปถ
+ router.Use(gin.Logger())
+ router.Use(gin.Recovery())
+
+ //ๅ
ฅๅๆ ก้ช
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ zap.S().Info("ๅ
ฅๅๆ ก้ช test log here")
+ _ = v.RegisterValidation("ttValidation", helper.TtValidation)
+ }
+
+ //่ทฏ็ฑ็ป็ป
+ funcRouter := router.Group("/funcs")
+ {
+ funcRouter.GET("/:funcName", path.TtWeb)
+ }
+
+ //serverๅพฎ่ฐ
+ endless.DefaultReadTimeOut = 10 * time.Second
+ endless.DefaultWriteTimeOut = 10 * time.Second
+ endless.DefaultMaxHeaderBytes = 1 << 20
+ return endless.ListenAndServe(listeningPort, router)
+}
diff --git a/cmd/ttserver/main.go b/cmd/ttserver/main.go
new file mode 100644
index 00000000..2ec65b58
--- /dev/null
+++ b/cmd/ttserver/main.go
@@ -0,0 +1,24 @@
+package ttserver
+
+import (
+ "os"
+
+ ttserverapp "github.com/Slahser/coup-de-grace/cmd/ttserver/app"
+
+ "github.com/Slahser/coup-de-grace/internal/app/helper"
+ "go.uber.org/zap"
+)
+
+func main() {
+
+ //ๅ
จๅฑlogger้
็ฝฎ
+ logger := helper.InitLogger()
+ undo := zap.ReplaceGlobals(logger)
+ defer undo()
+
+ //web serverๅฏๅจ
+ if err := ttserverapp.Run(); err != nil {
+ os.Exit(1)
+ }
+ os.Exit(0)
+}
diff --git a/deployments/buildkit/README.md b/deployments/buildkit/README.md
new file mode 100644
index 00000000..32655c00
--- /dev/null
+++ b/deployments/buildkit/README.md
@@ -0,0 +1,42 @@
+# BuildKit Examples
+
+https://stackoverflow.com/questions/58508711/using-docker-buildkits-go-client-how-do-i-add-an-entrypoint
+https://github.com/moby/moby/blob/master/image/spec/v1.2.md
+
+## Kubernetes manifests
+- [`./kubernetes`](./kubernetes): Kubernetes manifests (`Pod`, `Deployment`, `StatefulSet`, `Job`)
+
+## CLI examples
+- [`./buildctl-daemonless`](./buildctl-daemonless): buildctl without daemon
+- [`./build-using-dockerfile`](./build-using-dockerfile): an example BuildKit client with `docker build`-style CLI
+
+## LLB examples
+
+For understanding the basics of LLB, `buildkit*` directory contains scripts that define how to build different configurations of BuildKit itself and its dependencies using the `client` package. Running one of these scripts generates a protobuf definition of a build graph. Note that the script itself does not execute any steps of the build.
+
+You can use `buildctl debug dump-llb` to see what data is in this definition. Add `--dot` to generate dot layout.
+
+```bash
+go run examples/buildkit0/buildkit.go \
+ | buildctl debug dump-llb \
+ | jq .
+```
+
+To start building use `buildctl build` command. The example script accepts `--with-containerd` flag to choose if containerd binaries and support should be included in the end result as well.
+
+```bash
+go run examples/buildkit0/buildkit.go \
+ | buildctl build
+```
+
+`buildctl build` will show interactive progress bar by default while the build job is running. If the path to the trace file is specified, the trace file generated will contain all information about the timing of the individual steps and logs.
+
+Different versions of the example scripts show different ways of describing the build definition for this project to show the capabilities of the library. New versions have been added when new features have become available.
+
+- `./buildkit0` - uses only exec operations, defines a full stage per component.
+- `./buildkit1` - cloning git repositories has been separated for extra concurrency.
+- `./buildkit2` - uses git sources directly instead of running `git clone`, allowing better performance and much safer caching.
+- `./buildkit3` - allows using local source files for separate components eg. `./buildkit3 --runc=local | buildctl build --local runc-src=some/local/path`
+- `./dockerfile2llb` - can be used to convert a Dockerfile to LLB for debugging purposes
+- `./nested-llb` - shows how to use nested invocation to generate LLB
+- `./gobuild` - shows how to use nested invocation to generate LLB for Go package internal dependencies
diff --git a/deployments/buildkit/buildkit0/buildkit.go b/deployments/buildkit/buildkit0/buildkit.go
new file mode 100644
index 00000000..233bbaf9
--- /dev/null
+++ b/deployments/buildkit/buildkit0/buildkit.go
@@ -0,0 +1,91 @@
+package main
+
+import (
+ "flag"
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/util/system"
+)
+
+type buildOpt struct {
+ withContainerd bool
+ containerd string
+ runc string
+}
+
+func main() {
+ var opt buildOpt
+ flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
+ flag.StringVar(&opt.containerd, "containerd", "v1.2.9", "containerd version")
+ flag.StringVar(&opt.runc, "runc", "v1.0.0-rc8", "runc version")
+ flag.Parse()
+
+ bk := buildkit(opt)
+ out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
+
+ dt, err := out.Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
+
+func goBuildBase() llb.State {
+ goAlpine := llb.Image("docker.io/library/golang:1.13-alpine")
+ return goAlpine.
+ AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
+ AddEnv("GOPATH", "/go").
+ Run(llb.Shlex("apk add --no-cache g++ linux-headers")).
+ Run(llb.Shlex("apk add --no-cache git libseccomp-dev make")).Root()
+}
+
+func runc(version string) llb.State {
+ return goBuildBase().
+ Run(llb.Shlex("git clone https://github.com/opencontainers/runc.git /go/src/github.com/opencontainers/runc")).
+ Dir("/go/src/github.com/opencontainers/runc").
+ Run(llb.Shlexf("git checkout -q %s", version)).
+ Run(llb.Shlex("go build -o /usr/bin/runc ./")).Root()
+}
+
+func containerd(version string) llb.State {
+ return goBuildBase().
+ Run(llb.Shlex("apk add --no-cache btrfs-progs-dev")).
+ Run(llb.Shlex("git clone https://github.com/containerd/containerd.git /go/src/github.com/containerd/containerd")).
+ Dir("/go/src/github.com/containerd/containerd").
+ Run(llb.Shlexf("git checkout -q %s", version)).
+ Run(llb.Shlex("make bin/containerd")).Root()
+}
+
+func buildkit(opt buildOpt) llb.State {
+ src := goBuildBase().
+ Run(llb.Shlex("git clone https://github.com/moby/buildkit.git /go/src/github.com/moby/buildkit")).
+ Dir("/go/src/github.com/moby/buildkit")
+
+ buildkitdOCIWorkerOnly := src.
+ Run(llb.Shlex("go build -o /bin/buildkitd.oci_only -tags no_containerd_worker ./cmd/buildkitd"))
+
+ buildkitd := src.
+ Run(llb.Shlex("go build -o /bin/buildkitd ./cmd/buildkitd"))
+
+ buildctl := src.
+ Run(llb.Shlex("go build -o /bin/buildctl ./cmd/buildctl"))
+
+ r := llb.Image("docker.io/library/alpine:latest")
+ r = copy(buildctl.Root(), "/bin/buildctl", r, "/bin/")
+ r = copy(runc(opt.runc), "/usr/bin/runc", r, "/bin/")
+ if opt.withContainerd {
+ r = copy(containerd(opt.containerd), "/go/src/github.com/containerd/containerd/bin/containerd", r, "/bin/")
+ r = copy(buildkitd.Root(), "/bin/buildkitd", r, "/bin/")
+ } else {
+ r = copy(buildkitdOCIWorkerOnly.Root(), "/bin/buildkitd.oci_only", r, "/bin/")
+ }
+ return r
+}
+
+func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State {
+ cpImage := llb.Image("docker.io/library/alpine:latest")
+ cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath))
+ cp.AddMount("/src", src)
+ return cp.AddMount("/dest", dest)
+}
diff --git a/deployments/buildkit/buildkit1/buildkit.go b/deployments/buildkit/buildkit1/buildkit.go
new file mode 100644
index 00000000..bfb9ccbe
--- /dev/null
+++ b/deployments/buildkit/buildkit1/buildkit.go
@@ -0,0 +1,117 @@
+package main
+
+import (
+ "flag"
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/util/system"
+)
+
+type buildOpt struct {
+ withContainerd bool
+ containerd string
+ runc string
+}
+
+func main() {
+ var opt buildOpt
+ flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
+ flag.StringVar(&opt.containerd, "containerd", "v1.2.9", "containerd version")
+ flag.StringVar(&opt.runc, "runc", "v1.0.0-rc8", "runc version")
+ flag.Parse()
+
+ bk := buildkit(opt)
+ out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
+
+ dt, err := out.Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
+
+func goBuildBase() llb.State {
+ goAlpine := llb.Image("docker.io/library/golang:1.13-alpine")
+ return goAlpine.
+ AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
+ AddEnv("GOPATH", "/go").
+ Run(llb.Shlex("apk add --no-cache g++ linux-headers")).
+ Run(llb.Shlex("apk add --no-cache git libseccomp-dev make")).Root()
+}
+
+func runc(version string) llb.State {
+ return goBuildBase().
+ With(goFromGit("github.com/opencontainers/runc", version)).
+ Run(llb.Shlex("go build -o /usr/bin/runc ./")).
+ Root()
+}
+
+func containerd(version string) llb.State {
+ return goBuildBase().
+ Run(llb.Shlex("apk add --no-cache btrfs-progs-dev")).
+ With(goFromGit("github.com/containerd/containerd", version)).
+ Run(llb.Shlex("make bin/containerd")).Root()
+}
+
+func buildkit(opt buildOpt) llb.State {
+ src := goBuildBase().With(goFromGit("github.com/moby/buildkit", "master"))
+
+ buildkitdOCIWorkerOnly := src.
+ Run(llb.Shlex("go build -o /bin/buildkitd.oci_only -tags no_containerd_worker ./cmd/buildkitd")).Root()
+
+ buildkitd := src.
+ Run(llb.Shlex("go build -o /bin/buildkitd ./cmd/buildkitd")).Root()
+
+ buildctl := src.
+ Run(llb.Shlex("go build -o /bin/buildctl ./cmd/buildctl")).Root()
+
+ r := llb.Image("docker.io/library/alpine:latest").With(
+ copyFrom(buildctl, "/bin/buildctl", "/bin/"),
+ copyFrom(runc(opt.runc), "/usr/bin/runc", "/bin/"),
+ )
+
+ if opt.withContainerd {
+ return r.With(
+ copyFrom(containerd(opt.containerd), "/go/src/github.com/containerd/containerd/bin/containerd", "/bin/"),
+ copyFrom(buildkitd, "/bin/buildkitd", "/bin/"))
+ }
+ return r.With(copyFrom(buildkitdOCIWorkerOnly, "/bin/buildkitd.oci_only", "/bin/"))
+}
+
+// goFromGit is a helper for cloning a git repo, checking out a tag and copying
+// source directory into
+func goFromGit(repo, tag string) llb.StateOption {
+ src := llb.Image("docker.io/library/alpine:latest").
+ Run(llb.Shlex("apk add --no-cache git")).
+ Run(llb.Shlexf("git clone https://%[1]s.git /go/src/%[1]s", repo)).
+ Dirf("/go/src/%s", repo).
+ Run(llb.Shlexf("git checkout -q %s", tag)).Root()
+ return func(s llb.State) llb.State {
+
+ return s.With(copyFrom(src, "/go", "/")).Reset(s)
+ //return s.With(copyFrom(src, "/go", "/")).Reset(s).Async(func(ctx context.Context, s llb.State) (llb.State, error) {
+ // // TODO: add s.With(s2.DirValue) or s.With(llb.Dir(s2)) or s.Reset(s2, llb.DirMask)?
+ // dir, err := src.GetDir(ctx)
+ // if err != nil {
+ // return llb.State{}, err
+ // }
+ // return s.Dir(dir), nil
+ //})
+ }
+}
+
+// copyFrom has similar semantics as `COPY --from`
+func copyFrom(src llb.State, srcPath, destPath string) llb.StateOption {
+ return func(s llb.State) llb.State {
+ return copy(src, srcPath, s, destPath)
+ }
+}
+
+// copy copies files between 2 states using cp until there is no copyOp
+func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State {
+ cpImage := llb.Image("docker.io/library/alpine:latest")
+ cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath))
+ cp.AddMount("/src", src)
+ return cp.AddMount("/dest", dest)
+}
diff --git a/deployments/buildkit/buildkit2/buildkit.go b/deployments/buildkit/buildkit2/buildkit.go
new file mode 100644
index 00000000..c477603d
--- /dev/null
+++ b/deployments/buildkit/buildkit2/buildkit.go
@@ -0,0 +1,105 @@
+package main
+
+import (
+ "flag"
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/util/system"
+)
+
+type buildOpt struct {
+ withContainerd bool
+ containerd string
+ runc string
+}
+
+func main() {
+ var opt buildOpt
+ flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
+ flag.StringVar(&opt.containerd, "containerd", "v1.2.9", "containerd version")
+ flag.StringVar(&opt.runc, "runc", "v1.0.0-rc8", "runc version")
+ flag.Parse()
+
+ bk := buildkit(opt)
+ out := bk.Run(llb.Shlex("ls -l /bin")) // debug output
+
+ dt, err := out.Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
+
+func goBuildBase() llb.State {
+ goAlpine := llb.Image("docker.io/library/golang:1.13-alpine")
+ return goAlpine.
+ AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
+ AddEnv("GOPATH", "/go").
+ Run(llb.Shlex("apk add --no-cache g++ linux-headers libseccomp-dev make")).Root()
+}
+
+func goRepo(s llb.State, repo, ref string, g ...llb.GitOption) func(ro ...llb.RunOption) llb.State {
+ dir := "/go/src/" + repo
+ return func(ro ...llb.RunOption) llb.State {
+ es := s.Dir(dir).Run(ro...)
+ es.AddMount(dir, llb.Git(repo, ref, g...))
+ return es.AddMount(dir+"/bin", llb.Scratch())
+ }
+}
+
+func runc(version string) llb.State {
+ return goRepo(goBuildBase(), "github.com/opencontainers/runc", version)(
+ llb.Shlex("go build -o ./bin/runc ./"),
+ )
+}
+
+func containerd(version string) llb.State {
+ return goRepo(
+ goBuildBase().
+ Run(llb.Shlex("apk add --no-cache btrfs-progs-dev")).Root(),
+ "github.com/containerd/containerd", version, llb.KeepGitDir())(
+ llb.Shlex("make bin/containerd"),
+ )
+}
+
+func buildkit(opt buildOpt) llb.State {
+ run := goRepo(goBuildBase(), "github.com/moby/buildkit", "master")
+
+ buildkitdOCIWorkerOnly := run(llb.Shlex("go build -o ./bin/buildkitd.oci_only -tags no_containerd_worker ./cmd/buildkitd"))
+
+ buildkitd := run(llb.Shlex("go build -o ./bin/buildkitd ./cmd/buildkitd"))
+
+ buildctl := run(llb.Shlex("go build -o ./bin/buildctl ./cmd/buildctl"))
+
+ r := llb.Image("docker.io/library/alpine:latest").With(
+ copyAll(buildctl, "/bin"),
+ copyAll(runc(opt.runc), "/bin"),
+ )
+
+ if opt.withContainerd {
+ return r.With(
+ copyAll(containerd(opt.containerd), "/bin"),
+ copyAll(buildkitd, "/bin"))
+ }
+ return r.With(copyAll(buildkitdOCIWorkerOnly, "/bin"))
+}
+
+func copyAll(src llb.State, destPath string) llb.StateOption {
+ return copyFrom(src, "/.", destPath)
+}
+
+// copyFrom has similar semantics as `COPY --from`
+func copyFrom(src llb.State, srcPath, destPath string) llb.StateOption {
+ return func(s llb.State) llb.State {
+ return copy(src, srcPath, s, destPath)
+ }
+}
+
+// copy copies files between 2 states using cp until there is no copyOp
+func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State {
+ cpImage := llb.Image("docker.io/library/alpine:latest")
+ cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath))
+ cp.AddMount("/src", src)
+ return cp.AddMount("/dest", dest)
+}
diff --git a/deployments/buildkit/buildkit3/buildkit.go b/deployments/buildkit/buildkit3/buildkit.go
new file mode 100644
index 00000000..1e870f8d
--- /dev/null
+++ b/deployments/buildkit/buildkit3/buildkit.go
@@ -0,0 +1,122 @@
+package main
+
+import (
+ "flag"
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/util/system"
+)
+
+type buildOpt struct {
+ buildkit string
+ containerd string
+ runc string
+ withContainerd bool
+}
+
+func main() {
+ var opt buildOpt
+ flag.BoolVar(&opt.withContainerd, "with-containerd", true, "enable containerd worker")
+ flag.StringVar(&opt.containerd, "containerd", "v1.2.9", "containerd version")
+ flag.StringVar(&opt.runc, "runc", "v1.0.0-rc8", "runc version")
+ flag.StringVar(&opt.buildkit, "buildkit", "master", "buildkit version")
+ flag.Parse()
+
+ bk := buildkit(opt)
+ out := bk
+ dt, err := out.Marshal( llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
+
+func goBuildBase() llb.State {
+ goAlpine := llb.Image("docker.io/library/golang:1.13-alpine")
+ return goAlpine.
+ AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
+ AddEnv("GOPATH", "/go").
+ Run(llb.Shlex("apk add --no-cache g++ linux-headers libseccomp-dev make")).Root()
+}
+
+func goRepo(s llb.State, repo string, src llb.State) func(ro ...llb.RunOption) llb.State {
+ dir := "/go/src/" + repo
+ return func(ro ...llb.RunOption) llb.State {
+ es := s.Dir(dir).Run(ro...)
+ es.AddMount(dir, src, llb.Readonly)
+ return es.AddMount("/out", llb.Scratch())
+ }
+}
+
+func runc(version string) llb.State {
+ repo := "github.com/opencontainers/runc"
+ src := llb.Git(repo, version)
+ if version == "local" {
+ src = llb.Local("runc-src")
+ }
+ return goRepo(goBuildBase(), repo, src)(
+ llb.Shlex("go build -o /out/runc ./"),
+ )
+}
+
+func containerd(version string) llb.State {
+ repo := "github.com/containerd/containerd"
+ src := llb.Git(repo, version, llb.KeepGitDir())
+ if version == "local" {
+ src = llb.Local("containerd-src")
+ }
+ return goRepo(
+ goBuildBase().
+ Run(llb.Shlex("apk add --no-cache btrfs-progs-dev")).Root(),
+ repo, src)(
+ llb.Shlex("go build -o /out/containerd ./cmd/containerd"),
+ )
+}
+
+func buildkit(opt buildOpt) llb.State {
+ repo := "github.com/moby/buildkit"
+ src := llb.Git(repo, opt.buildkit)
+ if opt.buildkit == "local" {
+ src = llb.Local("buildkit-src")
+ }
+ run := goRepo(goBuildBase(), repo, src)
+
+ buildkitdOCIWorkerOnly := run(llb.Shlex("go build -o /out/buildkitd.oci_only -tags no_containerd_worker ./cmd/buildkitd"))
+
+ buildkitd := run(llb.Shlex("go build -o /out/buildkitd ./cmd/buildkitd"))
+
+ buildctl := run(llb.Shlex("go build -o /out/buildctl ./cmd/buildctl"))
+
+ r := llb.Scratch().With(
+ copyAll(buildctl, "/"),
+ copyAll(runc(opt.runc), "/"),
+ )
+
+ if opt.withContainerd {
+ return r.With(
+ copyAll(containerd(opt.containerd), "/"),
+ copyAll(buildkitd, "/"))
+ }
+ return r.With(copyAll(buildkitdOCIWorkerOnly, "/"))
+}
+
+func copyAll(src llb.State, destPath string) llb.StateOption {
+ return copyFrom(src, "/.", destPath)
+}
+
+// copyFrom has similar semantics as `COPY --from`
+func copyFrom(src llb.State, srcPath, destPath string) llb.StateOption {
+ return func(s llb.State) llb.State {
+ return copy(src, srcPath, s, destPath)
+ }
+}
+
+// copy copies files between 2 states using cp
+func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State {
+ return dest.File(llb.Copy(src, srcPath, destPath, &llb.CopyInfo{
+ AllowWildcard: true,
+ AttemptUnpack: true,
+ CreateDestPath: true,
+ }))
+}
diff --git a/deployments/buildkit/dockerfile2llb/main.go b/deployments/buildkit/dockerfile2llb/main.go
new file mode 100644
index 00000000..c257e042
--- /dev/null
+++ b/deployments/buildkit/dockerfile2llb/main.go
@@ -0,0 +1,49 @@
+package main
+
+import (
+ "flag"
+ "io/ioutil"
+ "log"
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/client/llb/imagemetaresolver"
+ "github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb"
+ "github.com/moby/buildkit/solver/pb"
+ "github.com/moby/buildkit/util/appcontext"
+)
+
+type buildOpt struct {
+ target string
+}
+
+func main() {
+ var opt buildOpt
+ flag.StringVar(&opt.target, "target", "", "target stage")
+ flag.Parse()
+
+ df, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ panic(err)
+ }
+
+ caps := pb.Caps.CapSet(pb.Caps.All())
+
+ state, img, err := dockerfile2llb.Dockerfile2LLB(appcontext.Context(), df, dockerfile2llb.ConvertOpt{
+ MetaResolver: imagemetaresolver.Default(),
+ Target: opt.target,
+ LLBCaps: &caps,
+ })
+ if err != nil {
+ log.Printf("err: %+v", err)
+ panic(err)
+ }
+
+ _ = img
+
+ dt, err := state.Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
diff --git a/deployments/buildkit/gobuild/main.go b/deployments/buildkit/gobuild/main.go
new file mode 100644
index 00000000..582447c4
--- /dev/null
+++ b/deployments/buildkit/gobuild/main.go
@@ -0,0 +1,96 @@
+// +build ignore
+
+package main
+
+import (
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ gobuild "github.com/tonistiigi/llb-gobuild"
+)
+
+func main() {
+ if err := run(); err != nil {
+ panic(err)
+ }
+}
+
+func run() error {
+ src := llb.Local("src")
+
+ gb := gobuild.New(nil)
+ // gb := gobuild.New(&gobuild.Opt{DevMode: true})
+
+ buildctl, err := gb.BuildExe(gobuild.BuildOpt{
+ Source: src,
+ MountPath: "/go/src/github.com/moby/buildkit",
+ Pkg: "github.com/moby/buildkit/cmd/buildctl",
+ BuildTags: []string{},
+ })
+ if err != nil {
+ return err
+ }
+
+ buildkitd, err := gb.BuildExe(gobuild.BuildOpt{
+ Source: src,
+ MountPath: "/go/src/github.com/moby/buildkit",
+ Pkg: "github.com/moby/buildkit/cmd/buildkitd",
+ BuildTags: []string{"no_containerd_worker"},
+ })
+ if err != nil {
+ return err
+ }
+ _ = buildkitd
+
+ containerd, err := gb.BuildExe(gobuild.BuildOpt{
+ Source: llb.Git("github.com/containerd/containerd", "v1.2.7"),
+ MountPath: "/go/src/github.com/containerd/containerd",
+ Pkg: "github.com/containerd/containerd/cmd/containerd",
+ BuildTags: []string{"no_btrfs"},
+ })
+ if err != nil {
+ return err
+ }
+ runc, err := gb.BuildExe(gobuild.BuildOpt{
+ CgoEnabled: true,
+ Source: llb.Git("github.com/opencontainers/runc", "master"),
+ MountPath: "/go/src/github.com/opencontainers/runc",
+ Pkg: "github.com/opencontainers/runc",
+ BuildTags: []string{},
+ })
+ if err != nil {
+ return err
+ }
+
+ sc := llb.Scratch().
+ With(copyAll(*buildctl, "/")).
+ With(copyAll(*containerd, "/")).
+ // With(copyAll(*buildkitd, "/")).
+ With(copyAll(*runc, "/"))
+
+ dt, err := sc.Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+ return nil
+}
+
+func copyAll(src llb.State, destPath string) llb.StateOption {
+ return copyFrom(src, "/.", destPath)
+}
+
+// copyFrom has similar semantics as `COPY --from`
+func copyFrom(src llb.State, srcPath, destPath string) llb.StateOption {
+ return func(s llb.State) llb.State {
+ return copy(src, srcPath, s, destPath)
+ }
+}
+
+// copy copies files between 2 states using cp until there is no copyOp
+func copy(src llb.State, srcPath string, dest llb.State, destPath string) llb.State {
+ cpImage := llb.Image("docker.io/library/alpine@sha256:1072e499f3f655a032e88542330cf75b02e7bdf673278f701d7ba61629ee3ebe")
+ cp := cpImage.Run(llb.Shlexf("cp -a /src%s /dest%s", srcPath, destPath))
+ cp.AddMount("/src", src, llb.Readonly)
+ return cp.AddMount("/dest", dest)
+}
diff --git a/deployments/buildkit/kubernetes/README.md b/deployments/buildkit/kubernetes/README.md
new file mode 100644
index 00000000..ba037428
--- /dev/null
+++ b/deployments/buildkit/kubernetes/README.md
@@ -0,0 +1,79 @@
+# Kubernetes manifests for BuildKit
+
+This directory contains Kubernetes manifests for `Pod`, `Deployment` (with `Service`), `StatefulSet`, and `Job`.
+* `Pod`: good for quick-start
+* `Deployment` + `Service`: good for random load balancing with registry-side cache
+* `StateFulset`: good for client-side load balancing, without registry-side cache
+* `Job`: good if you don't want to have daemon pods
+
+Using Rootless mode (`*.rootless.yaml`) is recommended because Rootless mode image is executed as non-root user (UID 1000) and doesn't need `securityContext.privileged`.
+
+:warning: Rootless mode may not work on some host kernels. See [`../../docs/rootless.md`](../../docs/rootless.md).
+
+See also ["Building Images Efficiently And Securely On Kubernetes With BuildKit" (KubeCon EU 2019)](https://kccnceu19.sched.com/event/MPX5).
+
+## `Pod`
+
+```console
+$ kubectl apply -f pod.rootless.yaml
+$ buildctl \
+ --addr kube-pod://buildkitd \
+ build --frontend dockerfile.v0 --local context=/path/to/dir --local dockerfile=/path/to/dir
+```
+
+If rootless mode doesn't work, try `pod.privileged.yaml`.
+
+:warning: `kube-pod://` connection helper requires Kubernetes role that can access `pods/exec` resources. If `pods/exec` is not accessible, use `Service` instead (See below).
+
+## `Deployment` + `Service`
+
+Setting up mTLS is highly recommended.
+
+`./create-certs.sh SAN [SAN...]` can be used for creating certificates.
+```console
+$ ./create-certs.sh 127.0.0.1
+```
+
+The daemon certificates is created as `Secret` manifest named `buildkit-daemon-certs`.
+```console
+$ kubectl apply -f .certs/buildkit-daemon-certs.yaml
+```
+
+Apply the `Deployment` and `Service` manifest:
+```console
+$ kubectl apply -f deployment+service.rootless.yaml
+$ kubectl scale --replicas=10 deployment/buildkitd
+```
+
+Run `buildctl` with TLS client certificates:
+```console
+$ kubectl port-forward service/buildkitd 1234
+$ buildctl \
+ --addr tcp://127.0.0.1:1234 \
+ --tlscacert .certs/client/ca.pem \
+ --tlscert .certs/client/cert.pem \
+ --tlskey .certs/client/key.pem \
+ build --frontend dockerfile.v0 --local context=/path/to/dir --local dockerfile=/path/to/dir
+```
+
+## `StatefulSet`
+`StatefulSet` is useful for consistent hash mode.
+
+```console
+$ kubectl apply -f statefulset.rootless.yaml
+$ kubectl scale --replicas=10 statefulset/buildkitd
+$ buildctl \
+ --addr kube-pod://buildkitd-4 \
+ build --frontend dockerfile.v0 --local context=/path/to/dir --local dockerfile=/path/to/dir
+```
+
+See [`./consistenthash`](consistenthash) for how to use consistent hashing.
+
+## `Job`
+
+```console
+$ kubectl apply -f job.rootless.yaml
+```
+
+To push the image to the registry, you also need to mount `~/.docker/config.json`
+and set `$DOCKER_CONFIG` to `/path/to/.docker` directory.
diff --git a/deployments/buildkit/kubernetes/consistenthash/README.md b/deployments/buildkit/kubernetes/consistenthash/README.md
new file mode 100644
index 00000000..3d28e255
--- /dev/null
+++ b/deployments/buildkit/kubernetes/consistenthash/README.md
@@ -0,0 +1,26 @@
+# Distributed Build with Consistent Hashing
+
+Demo for efficiently using BuildKit daemon-local cache with multi-node cluster
+
+## Deploy
+
+```console
+$ kubectl apply -f ../statefulset.rootless.yaml
+$ kubectl scale --replicas=10 statefulset/buildkitd
+```
+
+## Consistent hashing
+
+Define the key string for consistent hashing.
+
+For example, the key can be defined as `:`, e.g.
+`github.com/example/project:some/directory`.
+
+
+Then determine the pod that corresponds to the key:
+```console
+$ go build -o consistenthash .
+$ pod=$(./show-running-pods.sh | consistenthash $key)
+```
+
+You can connect to the pod using `export BUILDKIT_HOST=kube-pod://$pod`.
diff --git a/deployments/buildkit/kubernetes/consistenthash/main.go b/deployments/buildkit/kubernetes/consistenthash/main.go
new file mode 100644
index 00000000..ebe5f64f
--- /dev/null
+++ b/deployments/buildkit/kubernetes/consistenthash/main.go
@@ -0,0 +1,67 @@
+// Package main provides simple consistenthash commandline utility.
+/*
+Demo:
+
+ $ seq -f node-%.f 1 100 > /tmp/nodes
+ $ consistenthash < /tmp/nodes apple
+ node-42
+ $ consistenthash < /tmp/nodes banana
+ node-48
+ $ consistenthash < /tmp/nodes chocolate
+ node-2
+
+Modify /tmp/nodes and confirm that the result rarely changes.
+*/
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+
+ "github.com/pkg/errors"
+ "github.com/serialx/hashring"
+ "github.com/sirupsen/logrus"
+)
+
+func main() {
+ if err := xmain(); err != nil {
+ logrus.Fatal(err)
+ }
+}
+
+func xmain() error {
+ if len(os.Args) != 2 {
+ fmt.Fprintf(os.Stderr, "Usage: %s KEY\nNode list needs to be provided via stdin\n", os.Args[0])
+ os.Exit(1)
+ return errors.New("should not reach here")
+ }
+ key := os.Args[1]
+ stdin, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ return err
+ }
+ var nodes []string
+ for _, s := range strings.Split(string(stdin), "\n") {
+ s = strings.TrimSpace(s)
+ if s != "" {
+ nodes = append(nodes, s)
+ }
+ }
+ chosen, err := doConsistentHash(nodes, key)
+ if err != nil {
+ return err
+ }
+ fmt.Println(chosen)
+ return nil
+}
+
+func doConsistentHash(nodes []string, key string) (string, error) {
+ ring := hashring.New(nodes)
+ x, ok := ring.GetNode(key)
+ if !ok {
+ return "", errors.Errorf("no node found for key %q", key)
+ }
+ return x, nil
+}
diff --git a/deployments/buildkit/kubernetes/consistenthash/show-running-pods.sh b/deployments/buildkit/kubernetes/consistenthash/show-running-pods.sh
new file mode 100644
index 00000000..235e39df
--- /dev/null
+++ b/deployments/buildkit/kubernetes/consistenthash/show-running-pods.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+set -eu
+selector="app=buildkitd"
+kubectl get pods --selector=$selector --field-selector=status.phase=Running -o=go-template --template="{{range .items}}{{.metadata.name}}{{\"\n\"}}{{end}}" --sort-by="{.metadata.name}"
diff --git a/deployments/buildkit/kubernetes/create-certs.sh b/deployments/buildkit/kubernetes/create-certs.sh
new file mode 100644
index 00000000..13a0a5ff
--- /dev/null
+++ b/deployments/buildkit/kubernetes/create-certs.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+set -o errexit
+set -o nounset
+set -o pipefail
+set -o errtrace
+
+PRODUCT=buildkit
+DIR=./.certs
+if [[ "$#" -lt 1 ]]; then
+ echo "Usage: $0 SAN [SAN...]"
+ echo
+ echo "Example: $0 buildkitd.default.svc 127.0.0.1"
+ echo
+ echo "The following files will be created under ${DIR}"
+ echo "- daemon/{ca.pem,cert.pem,key.pem}"
+ echo "- client/{ca.pem,cert.pem,key.pem}"
+ echo "- ${PRODUCT}-daemon-certs.yaml"
+ echo "- ${PRODUCT}-client-certs.yaml"
+ echo "- SAN"
+ exit 1
+fi
+if ! command -v mkcert >/dev/null; then
+ echo "Missing mkcert (https://github.com/FiloSottile/mkcert)"
+ exit 1
+fi
+SAN=$@
+SAN_CLIENT=client
+
+mkdir -p $DIR ${DIR}/daemon ${DIR}/client
+(
+ cd $DIR
+ echo $SAN | tr " " "\n" >SAN
+ CAROOT=$(pwd) mkcert -cert-file daemon/cert.pem -key-file daemon/key.pem ${SAN} >/dev/null 2>&1
+ CAROOT=$(pwd) mkcert -client -cert-file client/cert.pem -key-file client/key.pem ${SAN_CLIENT} >/dev/null 2>&1
+ cp -f rootCA.pem daemon/ca.pem
+ cp -f rootCA.pem client/ca.pem
+ rm -f rootCA.pem rootCA-key.pem
+
+ kubectl create secret generic ${PRODUCT}-daemon-certs --dry-run -o yaml --from-file=./daemon >${PRODUCT}-daemon-certs.yaml
+ kubectl create secret generic ${PRODUCT}-client-certs --dry-run -o yaml --from-file=./client >${PRODUCT}-client-certs.yaml
+)
diff --git a/deployments/buildkit/kubernetes/deployment+service.privileged.yaml b/deployments/buildkit/kubernetes/deployment+service.privileged.yaml
new file mode 100644
index 00000000..ad7342c3
--- /dev/null
+++ b/deployments/buildkit/kubernetes/deployment+service.privileged.yaml
@@ -0,0 +1,61 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ replicas: 10
+ selector:
+ matchLabels:
+ app: buildkitd
+ template:
+ metadata:
+ labels:
+ app: buildkitd
+ spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master
+ args:
+ - --addr
+ - unix:///run/buildkit/buildkitd.sock
+ - --addr
+ - tcp://0.0.0.0:1234
+
+# the probe below will only work after Release v0.6.3
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+# the probe below will only work after Release v0.6.3
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+ privileged: true
+ ports:
+ - containerPort: 1234
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ ports:
+ - port: 80
+ protocol: TCP
+ selector:
+ app: buildkitd
diff --git a/deployments/buildkit/kubernetes/deployment+service.rootless.yaml b/deployments/buildkit/kubernetes/deployment+service.rootless.yaml
new file mode 100644
index 00000000..4addbc79
--- /dev/null
+++ b/deployments/buildkit/kubernetes/deployment+service.rootless.yaml
@@ -0,0 +1,81 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: buildkitd
+ template:
+ metadata:
+ labels:
+ app: buildkitd
+ annotations:
+ container.apparmor.security.beta.kubernetes.io/buildkitd: unconfined
+ container.seccomp.security.alpha.kubernetes.io/buildkitd: unconfined
+# see buildkit/docs/rootless.md for caveats of rootless mode
+ spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master-rootless
+ args:
+ - --addr
+ - unix:///run/user/1000/buildkit/buildkitd.sock
+ - --addr
+ - tcp://0.0.0.0:1234
+ - --tlscacert
+ - /certs/ca.pem
+ - --tlscert
+ - /certs/cert.pem
+ - --tlskey
+ - /certs/key.pem
+ - --oci-worker-no-process-sandbox
+# the probe below will only work after Release v0.6.3
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+# the probe below will only work after Release v0.6.3
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+# To change UID/GID, you need to rebuild the image
+ runAsUser: 1000
+ runAsGroup: 1000
+ ports:
+ - containerPort: 1234
+ volumeMounts:
+ - name: certs
+ readOnly: true
+ mountPath: /certs
+ volumes:
+# buildkit-daemon-certs must contain ca.pem, cert.pem, and key.pem
+ - name: certs
+ secret:
+ secretName: buildkit-daemon-certs
+---
+apiVersion: v1
+kind: Service
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ ports:
+ - port: 1234
+ protocol: TCP
+ selector:
+ app: buildkitd
diff --git a/deployments/buildkit/kubernetes/job.privileged.yaml b/deployments/buildkit/kubernetes/job.privileged.yaml
new file mode 100644
index 00000000..4d1e9392
--- /dev/null
+++ b/deployments/buildkit/kubernetes/job.privileged.yaml
@@ -0,0 +1,44 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: buildkit
+spec:
+ template:
+ spec:
+ restartPolicy: Never
+ initContainers:
+ - name: prepare
+ image: alpine:3.10
+ command:
+ - sh
+ - -c
+ - "echo FROM hello-world > /workspace/Dockerfile"
+ volumeMounts:
+ - name: workspace
+ mountPath: /workspace
+ containers:
+ - name: buildkit
+ image: moby/buildkit:master
+ command:
+ - buildctl-daemonless.sh
+ args:
+ - build
+ - --frontend
+ - dockerfile.v0
+ - --local
+ - context=/workspace
+ - --local
+ - dockerfile=/workspace
+# To push the image to a registry, add
+# `--output type=image,name=docker.io/username/image,push=true`
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - name: workspace
+ readOnly: true
+ mountPath: /workspace
+# To push the image, you also need to create `~/.docker/config.json` secret
+# and set $DOCKER_CONFIG to `/path/to/.docker` directory.
+ volumes:
+ - name: workspace
+ emptyDir: {}
diff --git a/deployments/buildkit/kubernetes/job.rootless.yaml b/deployments/buildkit/kubernetes/job.rootless.yaml
new file mode 100644
index 00000000..2c9b1af3
--- /dev/null
+++ b/deployments/buildkit/kubernetes/job.rootless.yaml
@@ -0,0 +1,57 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: buildkit
+spec:
+ template:
+ metadata:
+ annotations:
+ container.apparmor.security.beta.kubernetes.io/buildkit: unconfined
+ container.seccomp.security.alpha.kubernetes.io/buildkit: unconfined
+# see buildkit/docs/rootless.md for caveats of rootless mode
+ spec:
+ restartPolicy: Never
+ initContainers:
+ - name: prepare
+ image: alpine:3.10
+ command:
+ - sh
+ - -c
+ - "echo FROM hello-world > /workspace/Dockerfile"
+ securityContext:
+ runAsUser: 1000
+ runAsGroup: 1000
+ volumeMounts:
+ - name: workspace
+ mountPath: /workspace
+ containers:
+ - name: buildkit
+ image: moby/buildkit:master-rootless
+ env:
+ - name: BUILDKITD_FLAGS
+ value: --oci-worker-no-process-sandbox
+ command:
+ - buildctl-daemonless.sh
+ args:
+ - build
+ - --frontend
+ - dockerfile.v0
+ - --local
+ - context=/workspace
+ - --local
+ - dockerfile=/workspace
+# To push the image to a registry, add
+# `--output type=image,name=docker.io/username/image,push=true`
+ securityContext:
+# To change UID/GID, you need to rebuild the image
+ runAsUser: 1000
+ runAsGroup: 1000
+ volumeMounts:
+ - name: workspace
+ readOnly: true
+ mountPath: /workspace
+# To push the image, you also need to create `~/.docker/config.json` secret
+# and set $DOCKER_CONFIG to `/path/to/.docker` directory.
+ volumes:
+ - name: workspace
+ emptyDir: {}
diff --git a/deployments/buildkit/kubernetes/pod.privileged.yaml b/deployments/buildkit/kubernetes/pod.privileged.yaml
new file mode 100644
index 00000000..79d37cd4
--- /dev/null
+++ b/deployments/buildkit/kubernetes/pod.privileged.yaml
@@ -0,0 +1,26 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: buildkitd
+spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+ privileged: true
diff --git a/deployments/buildkit/kubernetes/pod.rootless.yaml b/deployments/buildkit/kubernetes/pod.rootless.yaml
new file mode 100644
index 00000000..814e225d
--- /dev/null
+++ b/deployments/buildkit/kubernetes/pod.rootless.yaml
@@ -0,0 +1,34 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ name: buildkitd
+ annotations:
+ container.apparmor.security.beta.kubernetes.io/buildkitd: unconfined
+ container.seccomp.security.alpha.kubernetes.io/buildkitd: unconfined
+# see buildkit/docs/rootless.md for caveats of rootless mode
+spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master-rootless
+ args:
+ - --oci-worker-no-process-sandbox
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+# To change UID/GID, you need to rebuild the image
+ runAsUser: 1000
+ runAsGroup: 1000
diff --git a/deployments/buildkit/kubernetes/statefulset.privileged.yaml b/deployments/buildkit/kubernetes/statefulset.privileged.yaml
new file mode 100644
index 00000000..ce606fe5
--- /dev/null
+++ b/deployments/buildkit/kubernetes/statefulset.privileged.yaml
@@ -0,0 +1,39 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ serviceName: buildkitd
+ podManagementPolicy: Parallel
+ replicas: 1
+ selector:
+ matchLabels:
+ app: buildkitd
+ template:
+ metadata:
+ labels:
+ app: buildkitd
+ spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+ privileged: true
diff --git a/deployments/buildkit/kubernetes/statefulset.rootless.yaml b/deployments/buildkit/kubernetes/statefulset.rootless.yaml
new file mode 100644
index 00000000..10754468
--- /dev/null
+++ b/deployments/buildkit/kubernetes/statefulset.rootless.yaml
@@ -0,0 +1,47 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ labels:
+ app: buildkitd
+ name: buildkitd
+spec:
+ serviceName: buildkitd
+ podManagementPolicy: Parallel
+ replicas: 1
+ selector:
+ matchLabels:
+ app: buildkitd
+ template:
+ metadata:
+ labels:
+ app: buildkitd
+ annotations:
+ container.apparmor.security.beta.kubernetes.io/buildkitd: unconfined
+ container.seccomp.security.alpha.kubernetes.io/buildkitd: unconfined
+# see buildkit/docs/rootless.md for caveats of rootless mode
+ spec:
+ containers:
+ - name: buildkitd
+ image: moby/buildkit:master-rootless
+ args:
+ - --oci-worker-no-process-sandbox
+ readinessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ livenessProbe:
+ exec:
+ command:
+ - buildctl
+ - debug
+ - workers
+ initialDelaySeconds: 5
+ periodSeconds: 30
+ securityContext:
+# To change UID/GID, you need to rebuild the image
+ runAsUser: 1000
+ runAsGroup: 1000
diff --git a/deployments/buildkit/nested-llb/main.go b/deployments/buildkit/nested-llb/main.go
new file mode 100644
index 00000000..0bdc7704
--- /dev/null
+++ b/deployments/buildkit/nested-llb/main.go
@@ -0,0 +1,39 @@
+package main
+
+import (
+ "os"
+
+ "github.com/moby/buildkit/client/llb"
+ "github.com/moby/buildkit/client/llb/llbbuild"
+ "github.com/moby/buildkit/util/system"
+)
+
+const url = "https://gist.githubusercontent.com/tonistiigi/03b4049f8cc3de059bd2a1a1d8643714/raw/b5960995d570d8c6d94db527e805edc6d5854268/buildprs.go"
+
+func main() {
+ build := goBuildBase().
+ Run(llb.Shlex("apk add --no-cache curl")).
+ Run(llb.Shlexf("curl -o /buildprs.go \"%s\"", url))
+
+ buildkitRepo := "github.com/moby/buildkit"
+
+ build = build.Run(llb.Shlex("sh -c \"go run /buildprs.go > /out/buildkit.llb.definition\""))
+ build.AddMount("/go/src/"+buildkitRepo, llb.Git(buildkitRepo, "master"))
+ pb := build.AddMount("/out", llb.Scratch())
+
+ built := pb.With(llbbuild.Build())
+
+ dt, err := llb.Image("docker.io/library/alpine:latest").Run(llb.Shlex("ls -l /out"), llb.AddMount("/out", built, llb.Readonly)).Marshal(llb.LinuxAmd64)
+ if err != nil {
+ panic(err)
+ }
+ llb.WriteTo(dt, os.Stdout)
+}
+
+func goBuildBase() llb.State {
+ goAlpine := llb.Image("docker.io/library/golang:1.13-alpine")
+ return goAlpine.
+ AddEnv("PATH", "/usr/local/go/bin:"+system.DefaultPathEnv).
+ AddEnv("GOPATH", "/go").
+ Run(llb.Shlex("apk add --no-cache g++ linux-headers make")).Root()
+}
diff --git a/deployments/buildkit/rootless.md b/deployments/buildkit/rootless.md
new file mode 100644
index 00000000..87b9f80a
--- /dev/null
+++ b/deployments/buildkit/rootless.md
@@ -0,0 +1,130 @@
+# Rootless mode
+
+Rootless mode allows running BuildKit daemon as a non-root user.
+
+## Distribution-specific hint
+Using Ubuntu kernel is recommended.
+
+### Ubuntu
+* No preparation is needed.
+* `overlayfs` snapshotter is used by default ([Ubuntu-specific kernel patch](https://kernel.ubuntu.com/git/ubuntu/ubuntu-bionic.git/commit/fs/overlayfs?id=3b7da90f28fe1ed4b79ef2d994c81efbc58f1144)).
+
+### Debian GNU/Linux
+* Add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or `/etc/sysctl.d`) and run `sudo sysctl -p`
+* `fuse-overlayfs` snapshotter is used by default.
+* To use `overlayfs` snapshotter (recommended), run `sudo modprobe overlay permit_mounts_in_userns=1` ([Debian-specific kernel patch, introduced in Debian 10](https://salsa.debian.org/kernel-team/linux/blob/283390e7feb21b47779b48e0c8eb0cc409d2c815/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch)). Put the configuration to `/etc/modprobe.d` for persistence.
+
+### Arch Linux
+* Add `kernel.unprivileged_userns_clone=1` to `/etc/sysctl.conf` (or `/etc/sysctl.d`) and run `sudo sysctl -p`
+* `fuse-overlayfs` snapshotter is used by default if running kernel >= 4.18.
+ Otherwise only `native` snapshotter can be used.
+
+### Fedora
+* If you don't have the latest `runc` (>= v1.0.0-rc91) installed and you have `crun` instead, you need to run `buildkitd` with `--oci-worker-binary=crun`.
+* `fuse-overlayfs` snapshotter is used by default.
+
+### RHEL/CentOS 8
+* No preparation is needed.
+* `fuse-overlayfs` snapshotter is used by default.
+
+### RHEL/CentOS 7
+* Add `user.max_user_namespaces=28633` to `/etc/sysctl.conf` (or `/etc/sysctl.d`) and run `sudo sysctl -p`
+* Old releases (<= 7.6) require [extra configuration steps](https://github.com/moby/moby/pull/40076).
+* Only `native` snapshotter can be used.
+
+### Container-Optimized OS from Google
+* :warning: Currently unsupported. See [#879](https://github.com/moby/buildkit/issues/879).
+
+## Known limitations
+* `fuse-overlayfs` is used instead of `overlayfs` on most distros.
+* Network mode is always set to `network.host`.
+* No support for `containerd` worker
+
+## Running BuildKit in Rootless mode
+
+[RootlessKit](https://github.com/rootless-containers/rootlesskit/) needs to be installed.
+
+```console
+$ rootlesskit buildkitd
+```
+
+```console
+$ buildctl --addr unix:///run/user/$UID/buildkit/buildkitd.sock build ...
+```
+
+## Troubleshooting
+If facing an error related to `fuse-overlayfs`, try running `buildkitd` with `--oci-worker-snapshotter=native`:
+
+```console
+$ rootlesskit buildkitd --oci-worker-snapshotter=native
+```
+
+## Containerized deployment
+
+### Kubernetes
+See [`../examples/kubernetes`](../examples/kubernetes).
+
+### Docker
+
+```console
+$ docker run \
+ --name buildkitd \
+ -d \
+ --security-opt seccomp=unconfined \
+ --security-opt apparmor=unconfined \
+ --device /dev/fuse \
+ moby/buildkit:rootless --oci-worker-no-process-sandbox
+$ buildctl --addr docker-container://buildkitd build ...
+```
+
+If you don't mind using `--privileged` (almost safe for rootless), the `docker run` flags can be shorten as follows:
+
+```console
+$ docker run --name buildkitd -d --privileged moby/buildkit:rootless
+```
+
+#### About `--device /dev/fuse`
+Adding `--device /dev/fuse` to the `docker run` arguments is required only if you want to use `fuse-overlayfs` snapshotter.
+
+#### About `--oci-worker-no-process-sandbox`
+
+By adding `--oci-worker-no-process-sandbox` to the `buildkitd` arguments, BuildKit can be executed in a container without adding `--privileged` to `docker run` arguments.
+However, you still need to pass `--security-opt seccomp=unconfined --security-opt apparmor=unconfined` to `docker run`.
+
+Note that `--oci-worker-no-process-sandbox` allows build executor containers to `kill` (and potentially `ptrace` depending on the seccomp configuration) an arbitrary process in the BuildKit daemon container.
+
+To allow running rootless `buildkitd` without `--oci-worker-no-process-sandbox`, run `docker run` with `--security-opt systempaths=unconfined`. (For Kubernetes, set `securityContext.procMount` to `Unmasked`.)
+
+The `--security-opt systempaths=unconfined` flag disables the masks for the `/proc` mount in the container and potentially allows reading and writing dangerous kernel files, but it is safe when you are running `buildkitd` as non-root.
+
+### Change UID/GID
+
+The `moby/buildkit:rootless` image has the following UID/GID configuration:
+
+Actual ID (shown in the host and the BuildKit daemon container)| Mapped ID (shown in build executor containers)
+----------|----------
+1000 | 0
+100000 | 1
+... | ...
+165535 | 65536
+
+```
+$ docker exec buildkitd id
+uid=1000(user) gid=1000(user)
+$ docker exec buildkitd ps aux
+PID USER TIME COMMAND
+ 1 user 0:00 rootlesskit buildkitd --addr tcp://0.0.0.0:1234
+ 13 user 0:00 /proc/self/exe buildkitd --addr tcp://0.0.0.0:1234
+ 21 user 0:00 buildkitd --addr tcp://0.0.0.0:1234
+ 29 user 0:00 ps aux
+$ docker exec cat /etc/subuid
+user:100000:65536
+```
+
+To change the UID/GID configuration, you need to modify and build the BuildKit image manually.
+```
+$ vi Dockerfile
+$ make images
+$ docker run ... moby/buildkit:local-rootless ...
+```
+
diff --git a/deployments/traefik-dynamic.yaml b/deployments/traefik-dynamic.yaml
new file mode 100644
index 00000000..fb7e77cb
--- /dev/null
+++ b/deployments/traefik-dynamic.yaml
@@ -0,0 +1,61 @@
+http:
+ routers:
+ tt-router:
+ entryPoints:
+ - "my-ep"
+ # rule: "Host(`example.com`) || (Host(`example.org`) && Path(`/foo`)"
+ # rule: "PathPrefix(`/prefix1/`, `/prefix2/{cat:[a-z]+}/{id:[0-9]+}`)"
+ rule: "Path(`/pathtt`)"
+ middlewares:
+ - authentication
+ service: my-service-with-weight
+ priority: 1
+ tt-router2:
+ entryPoints:
+ - "my-ep"
+ rule: "Path(`/pathtt`)"
+ service: my-service-with-weight
+ priority: 2
+
+ services:
+ my-service-with-weight-facade:
+ weighted:
+ services:
+ - name: tt-service-backend-kubeless
+ weight: 3
+ - name: tt-service-backend-nuclio
+ weight: 1
+ tt-service-backend-kubeless:
+ loadBalancer:
+ healthCheck:
+ scheme: http
+ port: 8080
+ path: /health
+ interval: "10s"
+ timeout: "3s"
+ servers:
+ - url: "http://private-ip-server-1/"
+ - url: "http://private-ip-server-2/"
+ tt-service-backend-nuclio:
+ loadBalancer:
+ healthCheck:
+ scheme: http
+ port: 8080
+ path: /health
+ interval: "10s"
+ timeout: "3s"
+ servers:
+ - url: "http://private-ip-server-1/"
+ - url: "http://private-ip-server-2/"
+
+
+
+
+
+# tcp:
+# routers:
+# to-database:
+# entryPoints:
+# - "mysql"
+# rule: "HostSNI(`*`)"
+# service: database
diff --git a/deployments/traefik-playground.yaml b/deployments/traefik-playground.yaml
new file mode 100644
index 00000000..da99e391
--- /dev/null
+++ b/deployments/traefik-playground.yaml
@@ -0,0 +1,121 @@
+apiVersion: traefik.containo.us/v1alpha1
+kind: Middleware
+metadata:
+ name: tt-addprefix
+ namespace: traefik-playground
+spec:
+ addPrefix:
+ prefix: /prett
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: Middleware
+metadata:
+ name: tt-ratelimit
+ namespace: traefik-playground
+spec:
+ rateLimit:
+ average: 100
+ burst: 50
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: Middleware
+metadata:
+ name: tt-retry
+ namespace: traefik-playground
+spec:
+ retry:
+ attempts: 4
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: TraefikService
+metadata:
+ name: tts-self-hosted
+ namespace: traefik-playground
+
+spec:
+ weighted:
+ services:
+ - kind: Service
+ name: whoami
+ namespace: traefik-playground
+ weight: 3
+ scheme: http
+ port: 80
+ - kind: Service
+ name: whoami-impl2
+ namespace: traefik-playground
+ weight: 2
+ scheme: http
+ port: 80
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: TraefikService
+metadata:
+ name: tts-cloud-hosted
+ namespace: traefik-playground
+
+spec:
+ weighted:
+ services:
+ - kind: Service
+ name: whoami
+ namespace: traefik-playground
+ weight: 3
+ scheme: http
+ port: 80
+ - kind: Service
+ name: whoami-impl2
+ namespace: traefik-playground
+ weight: 2
+ scheme: http
+ port: 80
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: TraefikService
+metadata:
+ name: tts
+ namespace: traefik-playground
+
+spec:
+ weighted:
+ services:
+ - kind: TraefikService
+ name: tts-self-hosted
+ namespace: traefik-playground
+ weight: 3
+ - kind: TraefikService
+ name: tts-cloud-hosted
+ namespace: traefik-playground
+ weight: 2
+
+---
+apiVersion: traefik.containo.us/v1alpha1
+kind: IngressRoute
+metadata:
+ name: tt-ingressroute
+ namespace: traefik-playground
+
+spec:
+ entryPoints:
+ - web
+
+ routes:
+ - kind: Rule
+ # rule: "Host(`example.com`) || (Host(`example.org`) && Path(`/foo`)"
+ # rule: "PathPrefix(`/prefix1/`, `/prefix2/{cat:[a-z]+}/{id:[0-9]+}`)"
+ match: Path(`/pathtt`)
+ priority: 12
+ middlewares:
+ - name: tt-addprefix
+ namespace: traefik-playground
+ - name: tt-ratelimit
+ namespace: traefik-playground
+ - name: tt-retry
+ namespace: traefik-playground
+ services:
+ - name: tts
+ namespace: traefik-playground
+ kind: TraefikService
diff --git a/deployments/traefik-static.yaml b/deployments/traefik-static.yaml
new file mode 100644
index 00000000..4e18838d
--- /dev/null
+++ b/deployments/traefik-static.yaml
@@ -0,0 +1,19 @@
+## Static configuration
+entryPoints:
+ my-ep:
+ address: ":8848"
+ forwardedHeaders:
+ insecure: true
+ transport:
+ respondingTimeouts:
+ readTimeout: 0
+ writeTimeout: 0
+ idleTimeout: 0
+ lifeCycle:
+ graceTimeOut: 30
+ requestAcceptGraceTimeout: 0
+ # http:
+ # redirections:
+ # entryPoint:
+ # to: websecure
+ # scheme: https
diff --git a/examples/playground_test.go b/examples/playground_test.go
new file mode 100644
index 00000000..8bf56dc9
--- /dev/null
+++ b/examples/playground_test.go
@@ -0,0 +1,40 @@
+package examples
+
+import (
+ "fmt"
+ "log"
+ "testing"
+
+ "github.com/gorilla/websocket"
+ "github.com/parnurzeal/gorequest"
+)
+
+func TestHTTPGet(t *testing.T) {
+ request := gorequest.New()
+ _, body, _ := request.Get("http://127.0.0.1:8080/tt/useraaaa").End()
+
+ if body != "Hello useraaaa" {
+ fmt.Print("not pass")
+ }
+}
+
+func TestHTTPPost(t *testing.T) {
+
+}
+
+func TestWSGet(t *testing.T) {
+
+ msg := "ping"
+
+ c, _, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8080/ping", nil)
+ if err != nil {
+ fmt.Errorf("dial: %w", err)
+ }
+ //defer c.Close()
+
+ werr := c.WriteMessage(websocket.TextMessage, []byte(msg))
+ if werr != nil {
+ log.Println("write:", werr)
+ return
+ }
+}
diff --git a/go.mod b/go.mod
index de79b352..2dd850d6 100644
--- a/go.mod
+++ b/go.mod
@@ -1,3 +1,74 @@
-module github.com/YOUR-USER-OR-ORG-NAME/YOUR-REPO-NAME
+module github.com/Slahser/coup-de-grace
-go 1.14
+go 1.15
+
+require (
+ github.com/c-bata/go-prompt v0.2.3
+ github.com/containous/traefik/v2 v2.2.11
+ github.com/coreos/etcd v3.3.25+incompatible
+ github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb
+ github.com/dimiro1/banner v1.0.0
+ github.com/felixge/fgprof v0.9.1
+ github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
+ github.com/gin-contrib/size v0.0.0-20200815104238-dc717522c4e2
+ github.com/gin-contrib/zap v0.0.1
+ github.com/gin-gonic/gin v1.6.3
+ github.com/go-errors/errors v1.1.1
+ github.com/go-openapi/strfmt v0.19.5 // indirect
+ github.com/go-playground/validator/v10 v10.3.0
+ github.com/goproxy/goproxy v0.2.1
+ github.com/gorilla/websocket v1.4.2
+ github.com/guptarohit/asciigraph v0.5.1
+ github.com/hashicorp/go-multierror v1.1.0
+ github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf
+ github.com/jedib0t/go-pretty v4.3.0+incompatible
+ github.com/jinzhu/configor v1.2.0
+ github.com/jpillora/opts v1.2.0
+ github.com/json-iterator/go v1.1.10
+ github.com/magefile/mage v1.10.0
+ github.com/mattn/go-tty v0.0.3 // indirect
+ github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
+ github.com/mitchellh/go-homedir v1.1.0
+ github.com/moby/buildkit v0.7.2
+ github.com/natefinch/lumberjack v2.0.0+incompatible
+ github.com/nuclio/nuclio v0.0.0-00010101000000-000000000000
+ github.com/nuclio/zap v0.0.3
+ github.com/parnurzeal/gorequest v0.2.16
+ github.com/pkg/errors v0.9.1
+ github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 // indirect
+ github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b
+ github.com/sirupsen/logrus v1.6.0
+ github.com/spf13/cobra v1.0.0
+ github.com/spf13/pflag v1.0.5
+ github.com/v3io/version-go v0.0.2
+ go.uber.org/zap v1.16.0
+ gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
+ k8s.io/apimachinery v0.19.1
+ k8s.io/client-go v0.19.1
+ moul.io/http2curl v1.0.0 // indirect
+)
+
+replace (
+ // Containous forks
+ github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
+ github.com/containerd/containerd => github.com/containerd/containerd v1.4.0
+
+ github.com/coreos/etcd => github.com/ozonru/etcd v3.3.20-grpc1.27-origmodule+incompatible
+ github.com/docker/docker => github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203
+ github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a
+ github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
+ github.com/gorilla/mux => github.com/containous/mux v0.0.0-20181024131434-c33f32e26898
+ github.com/hashicorp/go-immutable-radix => github.com/tonistiigi/go-immutable-radix v0.0.0-20170803185627-826af9ccf0fe
+ github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305
+ github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
+ github.com/mailgun/multibuf => github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba
+ github.com/nuclio/nuclio => ./third_party/nuclio
+
+ //replace github.com/coreos/go-systemd => github.com/coreos/go-systemd/v22 v22.0.0
+
+ google.golang.org/grpc => google.golang.org/grpc v1.27.0
+
+ k8s.io/api => k8s.io/api v0.16.9
+ k8s.io/apimachinery => k8s.io/apimachinery v0.16.9
+ k8s.io/client-go => k8s.io/client-go v0.16.9
+)
diff --git a/go.sum b/go.sum
new file mode 100644
index 00000000..d659e3c5
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,1360 @@
+bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
+cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
+cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
+cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
+cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
+cloud.google.com/go/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/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
+cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
+cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
+code.cloudfoundry.org/clock v1.0.0/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8=
+contrib.go.opencensus.io/exporter/ocagent v0.4.12/go.mod h1:450APlNTSR6FrvC3CTRqYosuDstRB9un7SOx2k/9ckA=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/AkihiroSuda/containerd-fuse-overlayfs v0.0.0-20200220082720-bb896865146c/go.mod h1:K4kx7xAA5JimeQCnN+dbeLlfaBxzZLaLiDD8lusFI8w=
+github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/azure-sdk-for-go v43.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Azure/go-autorest v10.8.1+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.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
+github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
+github.com/Azure/go-autorest/autorest v0.11.0/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
+github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
+github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
+github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
+github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM=
+github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
+github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
+github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
+github.com/Azure/go-autorest/autorest/to v0.2.0/go.mod h1:GunWKJp1AEqgMaGLV+iocmRAJWqST1wQYhyyjXJ3SJc=
+github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
+github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8=
+github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E=
+github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
+github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
+github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvdeRAgDr0izn4z5Ij88=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
+github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+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/DATA-DOG/godog v0.7.13/go.mod h1:z2OZ6a3X0/YAKVqLfVzYBwFt3j6uSt3Xrqa7XTtcQE0=
+github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
+github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
+github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61/go.mod h1:62qWSDaEI0BLykU+zQza5CAKgW0lOy9oBSz3/DvYz4w=
+github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
+github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
+github.com/Microsoft/ApplicationInsights-Go v0.4.2/go.mod h1:CukZ/G66zxXtI+h/VcVn3eVVDGDHfXM2zVILF7bMmsg=
+github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
+github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
+github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
+github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
+github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
+github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
+github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
+github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks=
+github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
+github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
+github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
+github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
+github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
+github.com/abronan/valkeyrie v0.0.0-20200127174252-ef4277a138cd/go.mod h1:2RUNONRAQ8bS1QcVJF3dYO/faiEro6NAAIQ6CqBkpD0=
+github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.18/go.mod h1:L+HB2uBoDgi3+r1pJEJcbGwyyHhd2QXaGsKLbDwtm8Q=
+github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/aliyun/alibaba-cloud-sdk-go v1.61.458/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
+github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U=
+github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
+github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
+github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
+github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
+github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
+github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/aws/aws-sdk-go v1.30.0/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
+github.com/aws/aws-sdk-go v1.30.20 h1:ktsy2vodSZxz/arYqo7DlpkIeNohHL+4Rmjdo7YGtrE=
+github.com/aws/aws-sdk-go v1.30.20/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
+github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
+github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
+github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
+github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
+github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
+github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
+github.com/c-bata/go-prompt v0.2.3/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
+github.com/c0va23/go-proxyprotocol v0.9.1/go.mod h1:TNjUV+llvk8TvWJxlPYAeAYZgSzT/iicNr3nWBWX320=
+github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs=
+github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
+github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
+github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
+github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
+github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
+github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
+github.com/cloudflare/cloudflare-go v0.13.2/go.mod h1:27kfc1apuifUmJhp069y0+hwlKDg4bd8LWlu7oKeZvM=
+github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
+github.com/codegangsta/negroni v1.0.0/go.mod h1:v0y3T5G7Y1UlFfyxFn/QLRU4a2EuNau2iZY63YTKWo0=
+github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
+github.com/containerd/cgroups v0.0.0-20200217135630-d732e370d46d/go.mod h1:CStdkl05lBnJej94BPFoJ7vB8cELKXwViS+dgfW0/M8=
+github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
+github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
+github.com/containerd/console v0.0.0-20191219165238-8375c3424e4d/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
+github.com/containerd/containerd v1.4.0 h1:aWJB3lbDEaOxg1mkTBAINY2a+NsoKbAeRYefJPPRY+o=
+github.com/containerd/containerd v1.4.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/continuity v0.0.0-20181001140422-bd77b46c8352/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
+github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY=
+github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
+github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
+github.com/containerd/go-cni v0.0.0-20200107172653-c154a49e2c75/go.mod h1:0mg8r6FCdbxvLDqCXwAx2rO+KA37QICjKL8+wHOG5OE=
+github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
+github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
+github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
+github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
+github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15 h1:+jgiLE5QylzgADj0Yldb4id1NQNRrDOROj7KDvY9PEc=
+github.com/containerd/ttrpc v0.0.0-20200121165050-0be804eadb15/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
+github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
+github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
+github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
+github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
+github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd/go.mod h1:BbQgeDS5i0tNvypwEoF1oNjOJw8knRAE1DnVvjDstcQ=
+github.com/containous/check v0.0.0-20170915194414-ca0bf163426a/go.mod h1:eQOqZ7GoFsLxI7jFKLs7+Nv2Rm1x4FyK8d2NV+yGjwQ=
+github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e/go.mod h1:s8kLgBQolDbsJOPVIGCEEv9zGAKUUf/685Gi0Qqg8z8=
+github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595/go.mod h1:+lHFbEasIiQVGzhVDVw/cn0ZaOzde2OwNncp1NhXV4c=
+github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba/go.mod h1:zkWcASFUJEst6QwCrxLdkuw1gvaKqmflEipm+iecV5M=
+github.com/containous/mux v0.0.0-20181024131434-c33f32e26898 h1:1srn9voikJGofblBhWy3WuZWqo14Ou7NaswNG/I2yWc=
+github.com/containous/mux v0.0.0-20181024131434-c33f32e26898/go.mod h1:z8WW7n06n8/1xF9Jl9WmuDeZuHAhfL+bwarNjsciwwg=
+github.com/containous/traefik/v2 v2.2.11 h1:8yAA8EomSCxc47uQ8lxk3o6kdkuzmCF3xwANv+TzcBM=
+github.com/containous/traefik/v2 v2.2.11/go.mod h1:MPlIS5Q9FsVHrbjIOflqS+5nEaYiPG1r5z1NMGdhAV8=
+github.com/coreos/bbolt v1.3.2 h1:wZwiHHUieZCquLkDL0B8UhzreNWsPHooDAG3q34zk0s=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/bbolt v1.3.3 h1:n6AiVyVRKQFNb6mJlwESEvvLoDyiTzXX7ORAUlkeBdY=
+github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
+github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
+github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
+github.com/cpu/goacmedns v0.0.3/go.mod h1:4MipLkI+qScwqtVxcNO6okBhbgRrr7/tKXUSgSL0teQ=
+github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
+github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
+github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb h1:6S+TKObz6+Io2c8IOkcbK4Sz7nj6RpEVU7TkvmsZZcw=
+github.com/deckarep/gosx-notifier v0.0.0-20180201035817-e127226297fb/go.mod h1:wf3nKtOnQqCp7kp9xB7hHnNlZ6m3NoiOxjrB9hFRq4Y=
+github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
+github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
+github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
+github.com/dimiro1/banner v1.0.0 h1:t16KGiaSKGawJJAzHhiOZ7/soer3CR8+GK8FG+UB5TU=
+github.com/dimiro1/banner v1.0.0/go.mod h1:B1JJ2lANkn1MHpV/PvaGV0UcZ7rHoj2dkYTkWI1kCOs=
+github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
+github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
+github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
+github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v0.0.0-20200227165822-2298e6a3fe24/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/distribution v0.0.0-20200223014041-6b972e50feee/go.mod h1:xgJxuOjyp98AvnpRTR1+lGOqQ493ylRnRPmewD5GWtc=
+github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
+github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
+github.com/docker/docker-credential-helpers v0.6.0/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
+github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
+github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203 h1:QeBh8wW8pIZKlXxlMOQ8hSCMdJA+2Z/bD/iDyCAS8XU=
+github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
+github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
+github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
+github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
+github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
+github.com/docker/go-units v0.3.1/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
+github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/libcompose v0.0.0-20190805081528-eac9fe1b8b03/go.mod h1:EyqDS+Iyca0hS44T7qIMTeO1EOYWWWNOGpufHu9R8cs=
+github.com/docker/libnetwork v0.8.0-dev.2.0.20200226230617-d8334ccdb9be/go.mod h1:93m0aTqz6z+g32wla4l4WxTrdtvBRmVzYRkYvasA5Z8=
+github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
+github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
+github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
+github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
+github.com/dsnet/compress v0.0.1 h1:PlZu0n3Tuv04TzpfPbrnI0HW/YwodEXDS+oPKahKF0Q=
+github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo=
+github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
+github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
+github.com/eapache/channels v1.1.0/go.mod h1:jMm2qB5Ubtg9zLd+inMZd2/NUvXgzmWXsDaLyQIGfH0=
+github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
+github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
+github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
+github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
+github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
+github.com/elastic/go-sysinfo v1.1.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0=
+github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
+github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
+github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
+github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
+github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
+github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
+github.com/exoscale/egoscale v0.23.0/go.mod h1:hRo78jkjkCDKpivQdRBEpNYF5+cVpCJCPDg2/r45KaY=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
+github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
+github.com/felixge/fgprof v0.9.1 h1:E6FUJ2Mlv043ipLOCFqo8+cHo9MhQ203E2cdEK/isEs=
+github.com/felixge/fgprof v0.9.1/go.mod h1:7/HK6JFtFaARhIljgP2IV8rJLIoHDoOYoUphsnGvqxE=
+github.com/felixge/httpsnoop v1.0.0/go.mod h1:3+D9sFq0ahK/JeJPhCBUV1xlf4/eIYrUQaxulT0VzX8=
+github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6 h1:6VSn3hB5U5GeA6kQw4TwWIWbOhtvR2hmbBJnTOtqTWc=
+github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6/go.mod h1:YxOVT5+yHzKvwhsiSIWmbAYM3Dr9AEEbER2dVayfBkg=
+github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s=
+github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
+github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/gin-contrib/size v0.0.0-20200815104238-dc717522c4e2 h1:by6FEjzchEcXiooLKIumgbxwVxrvSxZffdE3clPw3tE=
+github.com/gin-contrib/size v0.0.0-20200815104238-dc717522c4e2/go.mod h1:MnR4Tp9v4OBCvoGBMoYJc4Jh/KUDcfFSxfbWVs+BKuM=
+github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
+github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
+github.com/gin-contrib/zap v0.0.1 h1:wsX/ahRftxPiXpiUw0YqyHj+TQTKtv+DAFWH84G1Uvg=
+github.com/gin-contrib/zap v0.0.1/go.mod h1:vJJndZ8f44gsTHQrDPIB4YOZzwOwiEIdE0mMrZLOogk=
+github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
+github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
+github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
+github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
+github.com/go-acme/lego/v4 v4.0.1 h1:vPwbTYfw5+fOaON9rWCN43iNrPw5cdJBhNMnA8oxBTM=
+github.com/go-acme/lego/v4 v4.0.1/go.mod h1:pIFm5tWkXSgiAEfJ/XQCQIvX1cEvHFwbgLZyx8OVSUE=
+github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
+github.com/go-chi/cors v1.0.0/go.mod h1:K2Yje0VW/SJzxiyMYu6iPQYa7hMjQX2i/F491VChg1I=
+github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
+github.com/go-errors/errors v1.1.1 h1:ljK/pL5ltg3qoN+OtN6yCv9HWSfMwxSx90GJCZQxYNg=
+github.com/go-errors/errors v1.1.1/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
+github.com/go-openapi/errors v0.19.2 h1:a2kIyV3w+OS3S97zxUndRVD46+FhGOUBDFY7nmu4CsY=
+github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
+github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
+github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
+github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
+github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc=
+github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/strfmt v0.19.5 h1:0utjKrw+BAh8s57XE9Xz8DUBsVvPmRUB6styvl9wWIM=
+github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
+github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
+github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
+github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
+github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
+github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
+github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
+github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
+github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-playground/validator/v10 v10.3.0 h1:nZU+7q+yJoFmwvNgv/LnPUkwPal62+b2xXj0AU1Es7o=
+github.com/go-playground/validator/v10 v10.3.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
+github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
+github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/flock v0.7.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
+github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE=
+github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
+github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
+github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
+github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
+github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
+github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
+github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
+github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
+github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
+github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
+github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
+github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
+github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040 h1:i7RUpu0EybzQyQvPT7J3MmODs4+gPcHsD/pqW0uIYVo=
+github.com/google/pprof v0.0.0-20200615235658-03e1cf38a040/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/shlex v0.0.0-20150127133951-6f45313302b9 h1:JM174NTeGNJ2m/oLH3UOWOvWQQKd+BoL3hcSCUWFLt0=
+github.com/google/shlex v0.0.0-20150127133951-6f45313302b9/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
+github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
+github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
+github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
+github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI=
+github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
+github.com/gophercloud/gophercloud v0.6.1-0.20191122030953-d8ac278c1c9d/go.mod h1:ozGNgr9KYOVATV5jsgHl/ceCDXGuguqOZAzoQ/2vcNM=
+github.com/gophercloud/gophercloud v0.7.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
+github.com/gophercloud/utils v0.0.0-20200508015959-b0167b94122c/go.mod h1:ehWUbLQJPqS0Ep+CxeD559hsm9pthPXadJNKwZkp43w=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/goproxy/goproxy v0.2.1 h1:7l8X1rSWmHdnjh5KR4op2uYY5zboyg8u+p3ilIeViWs=
+github.com/goproxy/goproxy v0.2.1/go.mod h1:RBl5RC2xOI6vAoMSwmQFPbKXsTysPhjbWWnpThv5oAU=
+github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
+github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
+github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
+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/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY=
+github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI=
+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 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0 h1:bM6ZAFZmc/wPFaRDi0d5L7hGEZEx/2u+Tmr2evNHDiI=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
+github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw=
+github.com/guptarohit/asciigraph v0.5.1 h1:rzRUdibSt3ff75gVGtcUXQ0dEkNgG0A20fXkA8cOMsA=
+github.com/guptarohit/asciigraph v0.5.1/go.mod h1:9fYEfE5IGJGxlP1B+w8wHFy7sNZMhPtn59f0RLtpRFM=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
+github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
+github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
+github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
+github.com/hashicorp/uuid v0.0.0-20160311170451-ebb0a03e909c/go.mod h1:fHzc09UnyJyqyW+bFuq864eh+wC7dj65aXmXLRe5to0=
+github.com/heptiolabs/healthcheck v0.0.0-20180807145615-6ff867650f40/go.mod h1:NtmN9h8vrTveVQRLHcX2HQ5wIPBDCsZ351TGbZWgg38=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
+github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/icza/dyno v0.0.0-20180601094105-0c96289f9585/go.mod h1:FOWDLyFiAsx5UmipjsBYguvps42mgph4nRPwuci95qM=
+github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
+github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
+github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI=
+github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8=
+github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/influxdata/influxdb1-client v0.0.0-20190809212627-fc22c7df067e/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
+github.com/instana/go-sensor v1.5.1/go.mod h1:5dEieTqu59XZr2/X53xF2Px4v83aSRRZa/47VbxAVa4=
+github.com/ishidawataru/sctp v0.0.0-20191218070446-00ab2ac2db07/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg=
+github.com/jarcoal/httpmock v1.0.4 h1:jp+dy/+nonJE4g4xbVtl9QdrUNbn6/3hDT5R4nDIZnA=
+github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
+github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
+github.com/jedib0t/go-pretty v4.3.0+incompatible h1:CGs8AVhEKg/n9YbUenWmNStRW2PHJzaeDodcfvRAbIo=
+github.com/jedib0t/go-pretty v4.3.0+incompatible/go.mod h1:XemHduiw8R651AF9Pt4FwCTKeG3oo7hrHJAoznj9nag=
+github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
+github.com/jinzhu/configor v1.2.0 h1:u78Jsrxw2+3sGbGMgpY64ObKU4xWCNmNRJIjGVqxYQA=
+github.com/jinzhu/configor v1.2.0/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
+github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
+github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
+github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
+github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
+github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/jpillora/opts v1.2.0 h1:H8vWooV3P9nsqmCcPgxNZyIa7GPOWA1KQFsfAzIkCtE=
+github.com/jpillora/opts v1.2.0/go.mod h1:7p7X/vlpKZmtaDFYKs956EujFqA6aCrOkcCaS6UBcR4=
+github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
+github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
+github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.10.4 h1:jFzIFaf586tquEB5EhzQG0HwGNSlgAJpG53G6Ss11wc=
+github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/cpuid v0.0.0-20180405133222-e7e905edc00e/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
+github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
+github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8=
+github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
+github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
+github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
+github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
+github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad/go.mod h1:GyCk/ifDcqsU1tsRMMWqXANnTtxzcwEWscb7j5qmblM=
+github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807/go.mod h1:std11u6pTaNwryy0Hy1dTQNdHKka1jNpflEieKtv5VE=
+github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591/go.mod h1:EBQ0jeOrBpOTkquwjmJl4W6z5xqlf5oA2LZfTqRNcO0=
+github.com/linode/linodego v0.21.0/go.mod h1:UTpq1JUZD0CZsJ8rt+0CRkqbzrp1MbGakVPt2DXY5Mk=
+github.com/liquidweb/liquidweb-go v1.6.1/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ=
+github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
+github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
+github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
+github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHbhWwIz3z9eVmQ2rx82rulEMG0t+Q1bzfc9DYN4=
+github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f/go.mod h1:8heskWJ5c0v5J9WH89ADhyal1DOZcayll8fSbhB+/9A=
+github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
+github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
+github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
+github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
+github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
+github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
+github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
+github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
+github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
+github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
+github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k=
+github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
+github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
+github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
+github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI=
+github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
+github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
+github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
+github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
+github.com/mholt/archiver/v3 v3.3.0 h1:vWjhY8SQp5yzM9P6OJ/eZEkmi3UAbRrxCq48MxjAzig=
+github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
+github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
+github.com/minio/minio-go/v7 v7.0.5/go.mod h1:TA0CQCjJZHM5SJj9IjqR0NmpmQJ6bCbXifAJ3mUU6Hw=
+github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
+github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/moby/buildkit v0.7.2 h1:wp4R0QMXSqwjTJKhhWlJNOCSQ/OVPnsCf3N8rs09+vQ=
+github.com/moby/buildkit v0.7.2/go.mod h1:D3DN/Nl4DyMH1LkwpRUJuoghqdigdXd1A6HXt5aZS40=
+github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+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/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
+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/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
+github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
+github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
+github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
+github.com/nats-io/gnatsd v1.4.1/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ=
+github.com/nats-io/go-nats v1.7.2/go.mod h1:+t7RHT5ApZebkrQdnn6AhQJmhJJiKAvJUio1PiiCtj0=
+github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
+github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
+github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI=
+github.com/nrdcg/desec v0.5.0/go.mod h1:2ejvMazkav1VdDbv2HeQO7w+Ta1CGHqzQr27ZBYTuEQ=
+github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ=
+github.com/nrdcg/goinwx v0.8.1/go.mod h1:tILVc10gieBp/5PMvbcYeXM6pVQ+c9jxDZnpaR1UW7c=
+github.com/nrdcg/namesilo v0.2.1/go.mod h1:lwMvfQTyYq+BbjJd30ylEG4GPSS6PII0Tia4rRpRiyw=
+github.com/nuclio/errors v0.0.1/go.mod h1:it2rUqDarIL8PasLYZo0Q1Ebsx4NRPM+OyYYakgNyrQ=
+github.com/nuclio/errors v0.0.3 h1:eXi8DjLj5kn5X7TrVlpmt3lPfS3rueUKf/cIUmxV6x8=
+github.com/nuclio/errors v0.0.3/go.mod h1:it2rUqDarIL8PasLYZo0Q1Ebsx4NRPM+OyYYakgNyrQ=
+github.com/nuclio/logger v0.0.0-20190303161055-fc1e4b16d127/go.mod h1:ttazNAqTxKjQ7XrGDZxecumGa9KCIuJh88gzFY1mRXo=
+github.com/nuclio/logger v0.0.1 h1:e+vT/Ug65RC+u0QX2J+lq3P57ZBwJ1ZA6Q2LCEcViwE=
+github.com/nuclio/logger v0.0.1/go.mod h1:ttazNAqTxKjQ7XrGDZxecumGa9KCIuJh88gzFY1mRXo=
+github.com/nuclio/logger-appinsights v0.0.1/go.mod h1:SRy3eM+sWa2ZeI0QpJg1O0Ja+WcsRXtlE2oUjPMXNck=
+github.com/nuclio/nuclio-sdk-go v0.1.0 h1:Nf1Zuo8xZbhzNAaFJsnoRP7XJH1Va7xseRODhe9izHs=
+github.com/nuclio/nuclio-sdk-go v0.1.0/go.mod h1:NqMgotiF6Y0Ho4+i5AvJhH3FRKAyL4IMaMv/eoUOkKQ=
+github.com/nuclio/zap v0.0.2/go.mod h1:SUxPsgePvlyjx6c5MtGdB50pf0IQThtlyLwISLboeuc=
+github.com/nuclio/zap v0.0.3 h1:sQ8D7w4CcVUSFDlHK+8AZz/5Kfsv4p+waJ0aw9DnW80=
+github.com/nuclio/zap v0.0.3/go.mod h1:SUxPsgePvlyjx6c5MtGdB50pf0IQThtlyLwISLboeuc=
+github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs=
+github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
+github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
+github.com/onsi/ginkgo 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.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
+github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.5.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/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ=
+github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
+github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc6/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc9.0.20200102164712-2b52db75279c/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc9.0.20200221051241-688cf6d43cc4/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
+github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
+github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
+github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
+github.com/opentracing-contrib/go-stdlib v0.0.0-20171029140428-b1a47cfbdd75/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v0.0.0-20171003133519-1361b9cd60be/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
+github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
+github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
+github.com/oracle/oci-go-sdk v24.2.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
+github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
+github.com/ozonru/etcd v3.3.20-grpc1.27-origmodule+incompatible h1:CAG0PUvo1fen+ZEfxKJjFIc8GuuN5RuaBuCAuaP2Hno=
+github.com/ozonru/etcd v3.3.20-grpc1.27-origmodule+incompatible/go.mod h1:iIubILNIN6Jq9h8uiSLrN9L1tuj3iSSFwz3R61skm/A=
+github.com/parnurzeal/gorequest v0.2.16 h1:T/5x+/4BT+nj+3eSknXmCTnEVGSzFzPGdpqmUVVZXHQ=
+github.com/parnurzeal/gorequest v0.2.16/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
+github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
+github.com/pavius/zap v1.4.2-0.20180228181622-8d52692529b8 h1:WqLgmr/wj9TO5Sc6oYPQRAJBxuHE0NTeuVeFnT+FZVo=
+github.com/pavius/zap v1.4.2-0.20180228181622-8d52692529b8/go.mod h1:6FWOCx06uh50GClv8S2cfk3asqTJs3qq3ZNRtLZE77I=
+github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
+github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
+github.com/pierrec/lz4 v0.0.0-20190327172049-315a67e90e41/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
+github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
+github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
+github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03 h1:pd4YKIqCB0U7O2I4gWHgEUA2mCEOENmco0l/bM957bU=
+github.com/pkg/term v0.0.0-20200520122047-c3ffed290a03/go.mod h1:Z9+Ul5bCbBKnbCvdOWbLqTHhJiYV414CURZJba6L8qA=
+github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
+github.com/posener/complete v1.2.2-0.20190308074557-af07aa5181b3 h1:GqpA1/5oN1NgsxoSA4RH0YWTaqvUlQNeOpHXD/JRbOQ=
+github.com/posener/complete v1.2.2-0.20190308074557-af07aa5181b3/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
+github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
+github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
+github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
+github.com/prometheus/client_golang v0.9.3 h1:9iH4JKXLzFbOAdtqv/a+j8aewx2Y8lAjAydhbaScPF8=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
+github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
+github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
+github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.0 h1:7etb9YClo3a6HjLzfl6rIQaU+FDfi0VSX39io3aQ+DM=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
+github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
+github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
+github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA=
+github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac/go.mod h1:67sLWL17mVlO1HFROaTBmU71NB4R8UNCesFHhg0f6LQ=
+github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
+github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
+github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rs/xid v1.1.0/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sacloud/libsacloud v1.36.2/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg=
+github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
+github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
+github.com/sendgridlabs/go-kinesis v0.0.0-20190306160747-8de9069567f6/go.mod h1:I9bRR0d0lwwnDe38QwwnlsP6xr//d80Ag0cAaXB3DG4=
+github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
+github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002 h1:ka9QPuQg2u4LGipiZGsgkg3rJCo4iIUCy75FddM0GRQ=
+github.com/serialx/hashring v0.0.0-20190422032157-8b2912629002/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
+github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b h1:h+3JX2VoWTFuyQEo87pStk/a99dzIO1mM9KxIyLPGTU=
+github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/sirupsen/logrus v1.0.3/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
+github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
+github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
+github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
+github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
+github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/soheilhy/cmux v0.1.4 h1:0HKaf1o97UwFjHH9o5XsHUOF+tqmdA7KEzXLpiyaw0E=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
+github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI=
+github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/amqp v0.0.0-20190815230801-eade30b20f1d/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
+github.com/streadway/quantile v0.0.0-20150917103942-b0c588724d25/go.mod h1:lbP8tGiBjZ5YWIc2fzuRpTaz0b/53vT6PEs3QuAWzuU=
+github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/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.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
+github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
+github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/tedsuo/ifrit v0.0.0-20191009134036-9a97d0632f00/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0=
+github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
+github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
+github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
+github.com/tinylib/msgp v1.1.1/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/tonistiigi/fsutil v0.0.0-20200326231323-c2c7d7b0e144/go.mod h1:0G1sLZ/0ttFf09xvh7GR4AEECnjifHRNJN/sYbLianU=
+github.com/tonistiigi/go-immutable-radix v0.0.0-20170803185627-826af9ccf0fe/go.mod h1:/+MCh11CJf2oz0BXmlmqyopK/ad1rKkcOXPoYuPCJYU=
+github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
+github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305/go.mod h1:gXOLibKqQTRAVuVZ9gX7G9Ykky8ll8yb4slxsEMoY0c=
+github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
+github.com/tsenart/vegeta v6.3.0+incompatible/go.mod h1:Smz/ZWfhKRcyDDChZkG3CyTHdj87lHzio/HOCkbndXM=
+github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
+github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
+github.com/uber/jaeger-client-go v0.0.0-20180103221425-e02c85f9069e/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
+github.com/uber/jaeger-lib v1.2.1/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
+github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
+github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
+github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
+github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
+github.com/unrolled/render v1.0.2/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM=
+github.com/unrolled/secure v1.0.7/go.mod h1:uGc1OcRF8gCVBA+ANksKmvM85Hka6SZtQIbrKc3sHS4=
+github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
+github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/v3io/scaler-types v1.7.0 h1:ZTbJaYUxZgnPjiOWU64l74jCk5iRmEoA2ZxyzUQbtn0=
+github.com/v3io/scaler-types v1.7.0/go.mod h1:fnjcQnuYD8wTmkmsv7QLnXShuk5HNRRwfFHfR+khYRs=
+github.com/v3io/v3io-go v0.1.9/go.mod h1:5poBlcjZG5TiexRTYI44PE6tHzZz5Z60w+iS899pWtc=
+github.com/v3io/v3io-go-http v0.0.1/go.mod h1:GXYcR9MxgfbE3BJdkXki5EclvtS8Nxu2RQNLA8hMMog=
+github.com/v3io/version-go v0.0.2 h1:Ay2erlJmm9HUGc6IqOSaCIikbaZDQSXSCbuLSzg3l/Y=
+github.com/v3io/version-go v0.0.2/go.mod h1:ckuefSs0aXfU4QzfvmEiNUbbQk/h4nb6/RiMDS8ySGM=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
+github.com/valyala/fasthttp v1.14.0 h1:67bfuW9azCMwW/Jlq/C+VeihNpAuJMWkYPBig1gdi3A=
+github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
+github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
+github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ=
+github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
+github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
+github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY=
+github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg=
+github.com/vultr/govultr v0.5.0/go.mod h1:wZZXZbYbqyY1n3AldoeYNZK4Wnmmoq6dNFkvd5TV3ss=
+github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
+github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
+github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
+github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
+github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
+github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
+go.elastic.co/apm v1.7.0/go.mod h1:IYfi/330rWC5Kfns1rM+kY+RPkIdgUziRF6Cbm9qlxQ=
+go.elastic.co/apm/module/apmhttp v1.7.0/go.mod h1:70/fYU6lgIII213g7As10lm2Ca/ZkGixeJBoyfrGKes=
+go.elastic.co/apm/module/apmot v1.7.0/go.mod h1:d2HlJ5Wr8ZfSUvRobRVK5vCihOkk/K+rDUEA9ONMQL0=
+go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs=
+go.etcd.io/bbolt v1.3.1-etcd.8/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.2 h1:Z/90sZLPOeCy2PwprqkFa25PdkusRzaj9P8zm/KNyvk=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
+go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw=
+go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
+go.mongodb.org/mongo-driver v1.0.3 h1:GKoji1ld3tw2aC+GX1wbr/J2fX13yNacEYoJ8Nhr0yU=
+go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
+go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
+go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
+go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
+go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
+go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
+go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
+go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
+golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
+golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
+golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
+golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
+golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
+golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
+golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
+golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20170114055629-f2499483f923/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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/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-20190619014844-b5b0513f8c1b/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-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
+golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
+golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
+golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/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-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
+golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
+golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y=
+golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
+golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
+golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb h1:iKlO7ROJc6SttHKlxzwGytRtBUqX4VARrNTgP2YLX5M=
+golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw=
+gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0=
+gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ=
+google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
+google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
+google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
+google.golang.org/appengine v1.1.0 h1:igQkv0AAhEIvTEpD5LIpAfav2eeVO9HBTjvKHVJPRSs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
+google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
+google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
+google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200227132054-3f1135a288c9/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171 h1:xes2Q2k+d/+YNXVw0FpZkIDJiaux4OVrRKXRAzH6A0U=
+google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
+google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
+google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+gopkg.in/DATA-DOG/go-sqlmock.v1 v1.3.0/go.mod h1:OdE7CF6DbADk7lN8LIKRzRJTTZXIjtWgA5THM5lhBAw=
+gopkg.in/DataDog/dd-trace-go.v1 v1.19.0/go.mod h1:DVp8HmDh8PuTu2Z0fVVlBsyWaC++fzwVCaGWylTe3tg=
+gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
+gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
+gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
+gopkg.in/h2non/gock.v1 v1.0.15/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
+gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
+gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
+gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.60.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
+gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
+gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
+gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
+gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
+gopkg.in/ns1/ns1-go.v2 v2.4.2/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
+gopkg.in/redis.v5 v5.2.9/go.mod h1:6gtv0/+A4iM08kdRfocWYB3bLX2tebpNtfKlFT6H4mY=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
+gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98=
+gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g=
+gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
+gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
+gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
+gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
+gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
+honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
+k8s.io/api v0.16.9 h1:3vCx0WX9qcg1Hv4aQ/G1tiIKectGVuimvPVTJU4VOCA=
+k8s.io/api v0.16.9/go.mod h1:Y7dZNHs1Xy0mSwSlzL9QShi6qkljnN41yR8oWCRTDe8=
+k8s.io/apimachinery v0.16.9 h1:ESUZ4hMBUKF2kn2HBFL5zM/wQv4j/0uRbR7AjgqGJ4o=
+k8s.io/apimachinery v0.16.9/go.mod h1:Xk2vD2TRRpuWYLQNM6lT9R7DSFZUYG03SarNkbGrnKE=
+k8s.io/client-go v0.16.9 h1:6Eh4lMDxFtDzBkqid1AOL3bQ/pPYrulx8l23DXw4mRU=
+k8s.io/client-go v0.16.9/go.mod h1:ThjPlh7Kx+XoBFOCt775vx5J7atwY7F/zaFzTco5gL0=
+k8s.io/code-generator v0.16.9/go.mod h1:wFdrXdVi/UC+xIfLi+4l9elsTT/uEF61IfcN2wOLULQ=
+k8s.io/code-generator v0.17.3 h1:q/hDMk2cvFzSxol7k/VA1qCssR7VSMXHQHhzuX29VJ8=
+k8s.io/code-generator v0.17.3/go.mod h1:l8BLVwASXQZTo2xamW5mQNFCe1XPiAesVq7Y1t7PiQQ=
+k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
+k8s.io/gengo v0.0.0-20190822140433-26a664648505 h1:ZY6yclUKVbZ+SdWnkfY+Je5vrMpKOxmGeKRbsXVmqYM=
+k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
+k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
+k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
+k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
+k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
+k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
+k8s.io/kubernetes v1.13.0 h1:qTfB+u5M92k2fCCCVP2iuhgwwSOv1EkAkvQY1tQODD8=
+k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+k8s.io/utils v0.0.0-20190801114015-581e00157fb1 h1:+ySTxfHnfzZb9ys375PXNlLhkJPLKgHajBU0N62BDvE=
+k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
+launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM=
+modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw=
+modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
+modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
+modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
+modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
+moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8=
+moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE=
+mvdan.cc/xurls/v2 v2.1.0/go.mod h1:5GrSd9rOnKOpZaji1OZLYL/yeAAtGDlo/cFe+8K5n8E=
+pack.ag/amqp v0.12.5/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
+rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
+rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
+sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e h1:4Z09Hglb792X0kfOBBJUPFEyvVfQWrYT/l8h5EKA6JQ=
+sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
+sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
+sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
+zombiezen.com/go/capnproto2 v2.17.0+incompatible/go.mod h1:XO5Pr2SbXgqZwn0m0Ru54QBqpOf4K5AYBO+8LAOBQEQ=
diff --git a/internal/app/_your_app_/.keep b/internal/app/_your_app_/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/internal/app/helper/logger.go b/internal/app/helper/logger.go
new file mode 100644
index 00000000..041924c8
--- /dev/null
+++ b/internal/app/helper/logger.go
@@ -0,0 +1,46 @@
+package helper
+
+import (
+ "github.com/natefinch/lumberjack"
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+/**
+ usage:
+ global zap logger with following configuration
+ zap.S() means SugarLogger
+ zap.L() means ZapLogger
+*/
+var (
+ logFile = "./logs/tt.log"
+ logLevel = zapcore.DebugLevel
+ logKeepDays = 30
+)
+
+func InitLogger() *zap.Logger {
+ writeSyncer := getLogWriter()
+ encoder := getEncoder()
+ core := zapcore.NewCore(encoder, writeSyncer, logLevel)
+
+ logger := zap.New(core, zap.AddCaller())
+ return logger
+}
+
+func getEncoder() zapcore.Encoder {
+ encoderConfig := zap.NewProductionEncoderConfig()
+ encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
+ encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
+ return zapcore.NewJSONEncoder(encoderConfig)
+}
+
+func getLogWriter() zapcore.WriteSyncer {
+ lumberJackLogger := &lumberjack.Logger{
+ Filename: logFile,
+ MaxSize: 10,
+ MaxBackups: 5,
+ MaxAge: logKeepDays,
+ Compress: true,
+ }
+ return zapcore.AddSync(lumberJackLogger)
+}
diff --git a/internal/app/helper/validator.go b/internal/app/helper/validator.go
new file mode 100644
index 00000000..a2e7ca88
--- /dev/null
+++ b/internal/app/helper/validator.go
@@ -0,0 +1,16 @@
+package helper
+
+import (
+ "github.com/go-playground/validator/v10"
+)
+
+func NewValidator() *validator.Validate {
+ return validator.New()
+}
+
+var TtValidation validator.Func = func(fl validator.FieldLevel) bool {
+ //date, ok := fl.Field().Interface().(time.Time)
+ //if ok {
+ //}
+ return true
+}
diff --git a/internal/app/tt_library/tt_library1.go b/internal/app/tt_library/tt_library1.go
new file mode 100644
index 00000000..54d750e3
--- /dev/null
+++ b/internal/app/tt_library/tt_library1.go
@@ -0,0 +1,5 @@
+package tt_library
+
+func Tt1() {
+
+}
diff --git a/internal/app/tt_practice/tt_error_handle.go b/internal/app/tt_practice/tt_error_handle.go
new file mode 100644
index 00000000..8fd46f32
--- /dev/null
+++ b/internal/app/tt_practice/tt_error_handle.go
@@ -0,0 +1,32 @@
+package tt_practice
+
+import (
+ "github.com/go-errors/errors"
+ "github.com/hashicorp/go-multierror"
+)
+
+func TtErrorHandle() error {
+
+ var result error
+
+ if err := step1(); err != nil {
+ result = multierror.Append(result, err)
+ }
+ if err := step2(); err != nil {
+ result = multierror.Append(result, err)
+ }
+
+ return result
+}
+
+func step1() error {
+ var Crashed = errors.Errorf("step1")
+ return errors.New(Crashed)
+
+}
+
+func step2() error {
+ var Crashed = errors.Errorf("step2")
+ return errors.New(Crashed)
+
+}
diff --git a/internal/app/tt_practice/tt_prac_helper.go b/internal/app/tt_practice/tt_prac_helper.go
new file mode 100644
index 00000000..b18b2bbe
--- /dev/null
+++ b/internal/app/tt_practice/tt_prac_helper.go
@@ -0,0 +1,120 @@
+package tt_practice
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+func Abs(x int) int {
+ if x < 0 {
+ return -x
+ }
+ return x
+}
+
+func ThreeValues() (int, int, float32) {
+ return 5, 6, 7.5
+}
+
+/**
+Function
+*/
+func MinMax(a int, b int) (min int, max int) {
+ if a < b {
+ min = a
+ max = b
+ } else { // a = b or a < b
+ min = b
+ max = a
+ }
+ return
+}
+
+func Trace(s string) {
+ fmt.Println()
+ fmt.Println("entering:", s)
+}
+
+func Untrace(s string) {
+ fmt.Println()
+ fmt.Println("leaving:", s)
+}
+
+func Function1() {
+ fmt.Println()
+ fmt.Printf("In function1 at the top\n")
+ defer Function2()
+ fmt.Printf("In function1 at the bottom!\n")
+ return
+}
+
+func Function2() {
+ fmt.Println("Function2: Deferred until the end of the calling function!")
+}
+
+// this function changes reply:
+func Multiply(a, b int16, reply *int16) {
+ *reply = a * b
+}
+
+func Min(s ...int) int {
+ if len(s) == 0 {
+ return 0
+ }
+ min := s[0]
+ for _, v := range s {
+ if v < min {
+ min = v
+ }
+ }
+ return min
+}
+func upPerson(p *Person) {
+ p.firstName = strings.ToUpper(p.firstName)
+ p.lastName = strings.ToUpper(p.lastName)
+}
+
+func upPr(p *Pr) {
+ p.firstName = strings.ToUpper(p.firstName)
+ p.lastName = strings.ToUpper(p.lastName)
+}
+
+type struct1 struct {
+ i1 int
+ f1 float32
+ str string
+}
+
+type Person struct {
+ firstName string
+ lastName string
+}
+
+func LongWait() {
+ fmt.Println("Beginning longWait()")
+ time.Sleep(5 * 1e8) // sleep for 0.5 seconds
+ fmt.Println("End of longWait()")
+}
+
+func ShortWait() {
+ fmt.Println("Beginning shortWait()")
+ time.Sleep(2 * 1e8) // sleep for 0.2 seconds
+ fmt.Println("End of shortWait()")
+}
+
+func Pump1(ch chan int) {
+ for i := 0; ; i++ {
+ if i%4623127 == 0 {
+ ch <- i * 2
+ }
+ }
+}
+
+func Pump2(ch chan int) {
+ for i := 0; ; i++ {
+ if i%4623127 == 0 {
+ ch <- i + 5
+ }
+ }
+}
diff --git a/internal/app/tt_practice/tt_practice1.go b/internal/app/tt_practice/tt_practice1.go
new file mode 100644
index 00000000..834f9089
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice1.go
@@ -0,0 +1,280 @@
+package tt_practice
+
+import (
+ "fmt"
+ "github.com/Slahser/coup-de-grace/internal/pkg/tpkg"
+ structrueLog "github.com/sirupsen/logrus"
+ "io"
+ "log"
+ "math/rand"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type AudioOutput int
+
+const (
+ OutMute AudioOutput = iota // 0
+ OutMono // 1
+ OutStereo // 2
+ _
+ _
+ OutSurround // 5
+)
+
+func Tt1() {
+
+ Trace("tt_practice1#Tt1()")
+ defer Untrace("tt_practice1#Tt1()")
+
+ path := os.Getenv("PATH")
+ fmt.Printf("Path is %s\n", path)
+ fmt.Println(os.Environ())
+
+ fmt.Println(tpkg.Pi)
+
+ fmt.Println("tt")
+ fmt.Println(OutSurround)
+
+ var goos = runtime.GOOS
+ fmt.Printf("The operating system is: %s\n", goos)
+
+ t1, t2 := 1, "here t2"
+ t1Next := t1
+
+ fmt.Println(&t1)
+ fmt.Println(&t1Next == &t1) //ๅผ็ฑปๅ
+ fmt.Println(&t2)
+
+ timens := int64(time.Now().Nanosecond())
+ fmt.Println(timens)
+ rand.Seed(timens)
+ for i := 0; i < 5; i++ {
+ fmt.Printf("%2.2f / ", 100*rand.Float32())
+ }
+
+ var n int16 = 34
+ var m int32
+ // compiler error: cannot use n (type int16) as type int32 in assignment
+ //m = n
+ m = int32(n)
+ fmt.Println()
+ fmt.Printf("32 bit int is: %d\n", m)
+ fmt.Printf("16 bit int is: %d\n", n)
+
+ var c1 complex64 = 5 + 10i
+ fmt.Printf("The value is: %v", c1)
+
+ str := "This is an example of a string"
+ fmt.Println()
+ fmt.Printf("T/F? Does the string \"%s\" have prefix %s? ", str, "Th")
+ fmt.Printf("%t\n", strings.HasPrefix(str, "Th"))
+
+ orig := "Hey, how are you George?"
+ fmt.Printf("The original string is: %s\n", orig)
+ lower := strings.ToLower(orig)
+ fmt.Printf("The lowercase string is: %s\n", lower)
+ upper := strings.ToUpper(orig)
+ fmt.Printf("The uppercase string is: %s\n", upper)
+
+ orig2 := "666"
+ var an int
+ var newS string
+
+ fmt.Printf("The size of ints is: %d\n", strconv.IntSize)
+
+ an, _ = strconv.Atoi(orig2) //ๅฉ็จๅค่ฟๅๅผ็็นๆง๏ผ่ฟไบๅฝๆฐไผ่ฟๅ 2 ไธชๅผ๏ผ็ฌฌ 1 ไธชๆฏ่ฝฌๆขๅ็็ปๆ๏ผๅฆๆ่ฝฌๆขๆๅ๏ผ๏ผ็ฌฌ 2 ไธชๆฏๅฏ่ฝๅบ็ฐ็้่ฏฏ
+ fmt.Printf("The integer is: %d\n", an)
+ an = an + 5
+ newS = strconv.Itoa(an)
+ fmt.Printf("The new string is: %s\n", newS)
+
+ fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
+ _, _ = time.Parse("2006-01-02 15:04:05", "2020-06-27 01:04:36") //ๅฟฝ็ฅ้่ฏฏ
+
+ var i1 = 5555
+ //่ฟไธชๅฐๅๅฏไปฅๅญๅจๅจไธไธชๅซๅๆ้็็นๆฎๆฐๆฎ็ฑปๅไธญ
+ fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1)
+ //ไธไธชๆ้ๅ้ๅฏไปฅๆๅไปปไฝไธไธชๅผ็ๅ
ๅญๅฐๅ ๅฎๆๅ้ฃไธชๅผ็ๅ
ๅญๅฐๅ๏ผๅจ 32 ไฝๆบๅจไธๅ ็จ 4 ไธชๅญ่๏ผๅจ 64 ไฝๆบๅจไธๅ ็จ 8 ไธชๅญ่๏ผๅนถไธไธๅฎๆๆๅ็ๅผ็ๅคงๅฐๆ ๅ
ณ
+ var intP *int = &i1
+ //var p *type
+ fmt.Println(intP)
+ //็ฌฆๅท * ๅฏไปฅๆพๅจไธไธชๆ้ๅ๏ผๅฆ *intP๏ผ้ฃไนๅฎๅฐๅพๅฐ่ฟไธชๆ้ๆๅๅฐๅไธๆๅญๅจ็ๅผ๏ผ่ฟ่ขซ็งฐไธบๅๅผ็จ
+ fmt.Println(*intP)
+ *intP = 6666
+ //ๆ้่ฝฌ็งป ๅฝ็ถๅฏไปฅ็ปง็ปญๆไฝ
+ fmt.Println(*intP)
+ fmt.Println(i1)
+ //ๆ้็ไธไธช้ซ็บงๅบ็จๆฏไฝ ๅฏไปฅไผ ้ไธไธชๅ้็ๅผ็จ๏ผๅฆๅฝๆฐ็ๅๆฐ๏ผ๏ผ่ฟๆ ทไธไผไผ ้ๅ้็ๆท่ด
+
+ fmt.Println(Abs(-233))
+
+ an, err := strconv.Atoi(orig)
+ if err != nil {
+ fmt.Printf("orig is not an integer - error occur\n")
+ }
+
+ num1 := 100
+ switch num1 {
+ case 0: // ็ฉบๅๆฏ๏ผๅชๆๅฝ i == 0 ๆถๆไผ่ฟๅ
ฅๅๆฏ
+ case 1:
+ fmt.Println("It's equal to 1") // ๅฝ i == 0 ๆถๅฝๆฐไธไผ่ขซ่ฐ็จ
+
+ case 2:
+ fallthrough
+ case 3:
+ fmt.Println("It's equal to 2 or 3") // ๅฝ i == 0 ๆถๅฝๆฐไนไผ่ขซ่ฐ็จ
+
+ case 98, 99:
+ fmt.Println("It's equal to 98 or 99")
+ case 100:
+ fmt.Println("It's equal to 100")
+ default:
+ fmt.Println("It's not equal to 98 or 100")
+ }
+
+ //switch {
+ //case num1 > 98 && num1 < 99:
+ // fmt.Println("It's equal to 98 or 99")
+ //case num1 > 100:
+ // fmt.Println("It's equal to 100")
+ //}
+ //
+ //switch a, b := x[i], y[j] {
+ //case a < b:
+ // t = -1
+ //case a == b:
+ // t = 0
+ //case a > b:
+ // t = 1
+ //}
+
+ var i = 5
+
+ for i >= 0 {
+ i = i - 1
+ fmt.Printf("The variable i is now: %d\n", i)
+ }
+
+ str2 := "Chinese: ๆฅๆฌ่ช"
+ fmt.Printf("The length of str2 is: %d\n", len(str2))
+ for pos, char := range str2 {
+ fmt.Printf("character %c starts at byte position %d\n", char, pos)
+ }
+
+ fmt.Println()
+ fmt.Println("index int(rune) rune char bytes")
+ for index, rune := range str2 {
+ fmt.Printf("%-2d %d %U '%c' % X\n", index, rune, rune, rune, []byte(string(rune)))
+ }
+
+ i1, _, f1 := ThreeValues()
+ fmt.Printf("The int: %d, the float: %f \n", i1, f1)
+
+ var min, max int
+ min, max = MinMax(78, 65)
+ fmt.Printf("Minmium is: %d, Maximum is: %d\n", min, max)
+
+ //้ญๅ
ๆผ็คบ.ๅ
ถๅฎๆฏ่พๅๅผบ,ๆฒกๆๅฝๆฐ่ฟๅ,ๅชๆฏๅฎไน
+ n = 0
+ reply := &n //n็ๆ้
+ Multiply(10, 5, reply)
+ fmt.Println("Multiply *reply:", *reply) // Multiply: 50
+ fmt.Println("Multiply n:", n) // Multiply: 50
+
+ x := Min(1, 3, 2, 0)
+ fmt.Printf("The minimum is: %d\n", x)
+ slice := []int{7, 9, 3, 5, 1}
+ x = Min(slice...)
+ fmt.Printf("The minimum in the slice is: %d", x)
+
+ //ๅ
ณ้ฎๅญ defer ๅ
่ฎธๆไปฌ่ฟ่กไธไบๅฝๆฐๆง่กๅฎๆๅ็ๆถๅฐพๅทฅไฝ
+ Function1()
+
+ Dd1()
+ Dd2()
+
+ //่ฎฐๅฝๅบๅ
ฅๅ
+ _, _ = Funttt("funtt")
+
+ //callback
+ Callback(1, Add)
+
+ //ๅฟๅๅฝๆฐ
+ rangePlus := func(rr int) {
+ sum := 0
+ for i := 1; i <= rr; i++ {
+ sum += i
+ }
+ fmt.Println(sum)
+ }
+ rangePlus(100)
+
+ //็ดๆฅ่ฐ็จๅฟๅๅฝๆฐ
+ func() {
+ sum := 0
+ for i := 1; i <= 100; i++ {
+ sum += i
+ }
+ fmt.Println(sum)
+ }()
+
+ var f = Adder()
+ fmt.Print(f(1), " - ")
+ fmt.Print(f(20), " - ")
+ fmt.Print(f(300))
+ fmt.Println()
+}
+
+/**
+้ญๅ
,ๅจๅฝๆฐไฝไธบ่ฟๅๅผ็ๆ
ๅต,ๅฏนไธ็บงๅฝๆฐไฝ็จๅๅ
ๅ้็ๅฝฑๅ
+*/
+func Adder() func(int) int {
+ var x int
+ return func(delta int) int {
+ x += delta
+ return x
+ }
+}
+
+func Dd1() {
+ i := 0
+ defer fmt.Println(i) //ๆญคๅคๆฏๅชๆๅฐไธๆฌก0
+ i++
+ return
+}
+
+func Dd2() {
+ for i := 0; i < 5; i++ {
+ defer fmt.Printf("%d ", i)
+ }
+ fmt.Println("i will write next line and you will reverse")
+}
+
+func Funttt(s string) (n int, err error) {
+ fmt.Println()
+ defer func() {
+ log.Printf("Funttt(%q) = %d, %v\n", s, n, err)
+ fmt.Println()
+ structrueLog.WithFields(
+ structrueLog.Fields{
+ "timestamps": time.Now().Format("2006-01-02 15:04:05"),
+ "wtf": "yeah",
+ "defer": "yes",
+ "param": s,
+ "return": n,
+ }).Info("tt defer log")
+ }()
+ return 7, io.EOF
+}
+
+func Add(a, b int) {
+ fmt.Printf("The sum of %d and %d is: %d\n", a, b, a+b)
+}
+
+func Callback(y int, f func(int, int)) {
+ f(y, 2) // this becomes Add(1, 2)
+}
diff --git a/internal/app/tt_practice/tt_practice2.go b/internal/app/tt_practice/tt_practice2.go
new file mode 100644
index 00000000..1ea13872
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice2.go
@@ -0,0 +1,149 @@
+package tt_practice
+
+import (
+ "fmt"
+ "sort"
+)
+
+func Tt2() {
+
+ Trace("tt_practice2#Tt1()")
+ defer Untrace("tt_practice2#Tt1()")
+
+ //ๆฐ็ป
+ a := [...]string{"a", "b", "c", "d"}
+ //ๅ็
+ b := []string{"a", "b", "c", "d"}
+ for i := range a {
+ fmt.Println("Array item", i, "is", a[i]+b[i])
+ }
+
+ var arr1 [6]int
+ var slice1 []int = arr1[2:5] // item at index 5 not included!
+
+ // load the array with integers: 0,1,2,3,4,5
+ for i := 0; i < len(arr1); i++ {
+ arr1[i] = i
+ }
+
+ // print the slice
+ for i := 0; i < len(slice1); i++ {
+ fmt.Printf("Slice at %d is %d\n", i, slice1[i])
+ }
+
+ fmt.Printf("The length of arr1 is %d\n", len(arr1))
+ fmt.Printf("The length of slice1 is %d\n", len(slice1))
+ fmt.Printf("The capacity of slice1 is %d\n", cap(slice1)) //capacityไปฃ่กจไป่ตท็นๅผๅง,ๅฏไปฅๅๅณๆๅคงๆฉๅฑๅคๅฐ
+
+ // grow the slice
+ slice1 = slice1[0:4]
+ for i := 0; i < len(slice1); i++ {
+ fmt.Printf("Slice at %d is %d\n", i, slice1[i])
+ }
+ fmt.Printf("The length of slice1 is %d\n", len(slice1))
+ fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
+
+ // grow the slice beyond capacity
+ //slice1 = slice1[0:7 ] // panic: runtime error: slice bound out of range
+
+ //ๅช่ฝๅๅณๆไฝ ็ธๅฝไบ0:2
+ slice1 = slice1[:2]
+ for i := 0; i < len(slice1); i++ {
+ fmt.Printf("Slice at %d is %d\n", i, slice1[i])
+ }
+ fmt.Printf("The length of slice1 is %d\n", len(slice1))
+ fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
+
+ //ๅช่ฝๅๅณๆไฝ ็ธๅฝไบๅฐๅทฆ่พน็ๅๅณ็งปๅจ
+ slice1 = slice1[2:]
+ for i := 0; i < len(slice1); i++ {
+ fmt.Printf("Slice at %d is %d\n", i, slice1[i])
+ }
+ fmt.Printf("The length of slice1 is %d\n", len(slice1))
+ fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
+
+ //ๅช่ฝๅๅณๆไฝ ็ธๅฝไบ0:2
+ slice1 = slice1[:2]
+ for i := 0; i < len(slice1); i++ {
+ fmt.Printf("Slice at %d is %d\n", i, slice1[i])
+ }
+ fmt.Printf("The length of slice1 is %d\n", len(slice1))
+ fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
+
+ //่ฟๅไธไธช็ฑปๅไธบ T ็ๅๅงๅผ?
+ slice3 := make([]int, 5, 10)
+ fmt.Println(slice3)
+ //new(T) ไธบๆฏไธชๆฐ็็ฑปๅ T ๅ้
ไธ็ๅ
ๅญ๏ผๅๅงๅไธบ 0 ๅนถไธ่ฟๅ็ฑปๅไธบ * T ็ๅ
ๅญๅฐๅ
+ //ๅณๆฐ็ป็ๆ้ &[]int
+ slice4 := new([10]int)[0:5]
+ fmt.Println(slice4)
+
+ var slice5 []int = make([]int, 4)
+
+ slice5[0] = 1
+ slice5[1] = 2
+ slice5[2] = 3
+ slice5[3] = 4
+
+ for value := range slice5 {
+ fmt.Printf("Slice contains : %d\n", value)
+ }
+
+ for idx, value := range slice5 {
+ fmt.Printf("Slice at %d is: %d\n", idx, value)
+ }
+
+ var mapLit map[string]int
+ //var mapCreated map[string]float32
+ var mapAssigned map[string]int
+
+ mapLit = map[string]int{"one": 1, "two": 2}
+ mapCreated := make(map[string]float32)
+ mapAssigned = mapLit
+
+ mapCreated["key1"] = 4.5
+ mapCreated["key2"] = 3.14159
+ mapAssigned["two"] = 3
+
+ fmt.Printf("Map literal at \"one\" is: %d\n", mapLit["one"])
+ fmt.Printf("Map created at \"key2\" is: %f\n", mapCreated["key2"])
+ fmt.Printf("Map assigned at \"two\" is: %d\n", mapLit["two"])
+ fmt.Printf("Map literal at \"ten\" is: %d\n", mapLit["ten"])
+
+ if _, ok := mapLit["one"]; ok {
+ fmt.Printf("mapLit contains key one")
+ } else {
+ fmt.Printf("i like it ")
+ }
+
+ //mapๅ็
+ items := make([]map[int]int, 5)
+ for i := range items {
+ items[i] = make(map[int]int, 1)
+ items[i][1] = i
+ }
+ fmt.Printf("Version A: Value of items: %v\n", items)
+
+ fmt.Println()
+
+ barVal := map[string]int{"alpha": 34, "bravo": 56, "charlie": 23,
+ "delta": 87, "echo": 56, "foxtrot": 12,
+ "golf": 34, "hotel": 16, "indio": 87,
+ "juliet": 65, "kili": 43, "lima": 98}
+
+ //ๅผบ่กๅ็,ๆฒกๆkeysetไน
+ keys := make([]string, len(barVal))
+ i := 0
+ for k, _ := range barVal {
+ keys[i] = k
+ i++
+ }
+ sort.Strings(keys)
+ fmt.Println()
+ fmt.Println("sorted:")
+ for _, k := range keys {
+ fmt.Printf("Key: %v, Value: %v / ", k, barVal[k])
+ }
+ fmt.Println()
+
+}
diff --git a/internal/app/tt_practice/tt_practice3.go b/internal/app/tt_practice/tt_practice3.go
new file mode 100644
index 00000000..9dbf8f49
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice3.go
@@ -0,0 +1,264 @@
+package tt_practice
+
+import (
+ "fmt"
+ "math"
+)
+
+type Pr Person
+
+type innerS struct {
+ in1 int
+ in2 int
+}
+
+type outerS struct {
+ b int
+ c float32
+ int // anonymous field
+ innerS //anonymous field
+}
+
+type Shaper interface {
+ Area() float32
+}
+
+type Square struct {
+ side float32
+}
+
+type Rectangle struct {
+ length, width float32
+}
+
+type Circle struct {
+ radius float32
+}
+
+func (sq *Square) Area() float32 {
+ return sq.side * sq.side
+}
+
+func (r Rectangle) Area() float32 {
+ return r.length * r.width
+}
+
+func (c Circle) Area() float32 {
+ return c.radius * c.radius * math.Pi
+}
+
+type stockPosition struct {
+ ticker string
+ sharePrice float32
+ count float32
+}
+
+/* method to determine the value of a stock position */
+func (s stockPosition) getValue() float32 {
+ return s.sharePrice * s.count
+}
+
+type car struct {
+ make string
+ model string
+ price float32
+}
+
+/* method to determine the value of a car */
+func (c car) getValue() float32 {
+ return c.price
+}
+
+/* contract that defines different things that have value */
+type valuable interface {
+ getValue() float32
+}
+
+func showValue(asset valuable) {
+ fmt.Printf("Value of the asset is %f\n", asset.getValue())
+}
+
+type Buffer struct {
+ tt int
+}
+
+type ReadWrite interface {
+ Read(b Buffer) bool
+ Write(b Buffer) bool
+}
+
+type Lock interface {
+ Lock()
+ Unlock()
+}
+
+/**
+ๆฅๅฃๅตๅฅ
+*/
+type File interface {
+ ReadWrite
+ Lock
+ Close()
+}
+
+type Any interface{}
+
+type TopologicalGenus interface {
+ Rank() int
+}
+
+func (sq *Square) Rank() int {
+ return 1
+}
+
+func (r Rectangle) Rank() int {
+ return 2
+}
+
+type IDuck interface {
+ Quack()
+ Walk()
+}
+
+func DuckDance(duck IDuck) {
+ for i := 1; i <= 3; i++ {
+ duck.Quack()
+ duck.Walk()
+ }
+}
+
+type Bird struct {
+ // ...
+}
+
+func (b *Bird) Quack() {
+ fmt.Println("I am quacking!")
+}
+
+func (b *Bird) Walk() {
+ fmt.Println("I am walking!")
+}
+
+func Tt3() {
+ Trace("tt_practice3#Tt3()")
+ defer Untrace("tt_practice3#Tt3()")
+
+ ms := new(struct1)
+ ms.i1 = 10
+ ms.f1 = 15.5
+ ms.str = "Chris"
+ ms2 := &struct1{10, 15.5, "Chris2"}
+
+ fmt.Println(ms) //็ปๆไฝ
+ fmt.Println(ms2) //็ปๆไฝ
+ fmt.Println(&ms) //ๅ
ๅญๅฐๅ
+ fmt.Println(*ms) //็ปๆไฝๅ
ๅญๅฎ้
ๅญๅจๆฐๆฎ
+
+ // 1-struct as a value type:
+ var pers1 Person
+ pers1.firstName = "Chris"
+ pers1.lastName = "Woodward"
+ upPerson(&pers1)
+ fmt.Printf("The name of the person is %s %s\n", pers1.firstName, pers1.lastName)
+
+ // 2โstruct as a pointer:
+ pers2 := new(Pr)
+ pers2.firstName = "Chris"
+ pers2.lastName = "Woodward"
+ (*pers2).lastName = "Woodward" // ่ฟๆฏๅๆณ็
+ upPr(pers2)
+ fmt.Printf("The name of the person is %s %s\n", pers2.firstName, pers2.lastName)
+
+ // 3โstruct as a literal:
+ pers3 := &Person{"Chris", "Woodward"}
+ upPerson(pers3)
+ fmt.Printf("The name of the person is %s %s\n", pers3.firstName, pers3.lastName)
+
+ outer := new(outerS)
+ outer.b = 6
+ outer.c = 7.5
+ outer.int = 60
+ outer.in1 = 5
+ outer.in2 = 10
+
+ fmt.Printf("outer.b is: %d\n", outer.b)
+ fmt.Printf("outer.c is: %f\n", outer.c)
+ fmt.Printf("outer.int is: %d\n", outer.int)
+ fmt.Printf("outer.in1 is: %d\n", outer.in1)
+ fmt.Printf("outer.in2 is: %d\n", outer.in2)
+
+ // ไฝฟ็จ็ปๆไฝๅญ้ข้
+ outer2 := outerS{6, 7.5, 60, innerS{5, 10}}
+ fmt.Println("outer2 is:", outer2)
+
+ r := Rectangle{5, 3} // Area() of Rectangle needs a value
+ q := &Square{5} // Area() of Square needs a pointer
+ // shapes := []Shaper{Shaper(r), Shaper(q)}
+ // or shorter
+ shapes := []Shaper{r, q}
+ fmt.Println("Looping through shapes for area ...")
+ for n, _ := range shapes {
+ fmt.Println("Shape details: ", shapes[n])
+ fmt.Println("Area of this shape is: ", shapes[n].Area())
+ }
+
+ var o valuable = stockPosition{"GOOG", 577.20, 4}
+ showValue(o)
+ o = car{"BMW", "M3", 66500}
+ showValue(o)
+
+ //็ฑปๅๆญ่จ
+ if v, ok := o.(valuable); ok { // checked type assertion
+ fmt.Printf("็ฑปๅๆญ่จ %s", v)
+ }
+
+ fmt.Println()
+ var areaIntf Shaper
+ sq1 := new(Square)
+ sq1.side = 5
+
+ areaIntf = sq1
+ // Is Square the type of areaIntf?
+ if t, ok := areaIntf.(*Square); ok {
+ fmt.Printf("The type of areaIntf is: %T\n", t)
+ }
+ if _, ok := areaIntf.(*Circle); ok {
+ fmt.Printf("The type of areaIntf is Circle")
+ } else {
+ fmt.Println("areaIntf does not contain a variable of type Circle")
+ }
+
+ //็ฑปๅๆญ่จ
+ switch t := areaIntf.(type) {
+ case *Square:
+ fmt.Printf("Type Square %T with value %v\n", t, t)
+ case *Circle:
+ fmt.Printf("Type Circle %T with value %v\n", t, t)
+ case nil:
+ fmt.Printf("nil value: nothing to check?\n")
+ default:
+ fmt.Printf("Unexpected type %T\n", t)
+ }
+
+ fmt.Println()
+
+ //ๆฅๅฃๆๅ
+
+ topgen := []TopologicalGenus{r, q}
+
+ //topoMap := make(map[int]TopologicalGenus, len(topgen))
+ //keys := make([]int, len(topgen))
+ //sort.Ints(keys)
+
+ fmt.Println("Looping through topgen for rank ...")
+
+ for n, _ := range topgen {
+ fmt.Println("Shape details: ", topgen[n])
+ fmt.Println("Topological Genus of this shape is: ", topgen[n].Rank())
+ }
+
+ //ๆญฃไบคไธๅจๆ็ฑปๅ
+ b := new(Bird)
+ DuckDance(b)
+
+}
diff --git a/internal/app/tt_practice/tt_practice4.go b/internal/app/tt_practice/tt_practice4.go
new file mode 100644
index 00000000..7eb48658
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice4.go
@@ -0,0 +1,115 @@
+package tt_practice
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+)
+
+/**
+Method
+func (recv receiver_type) methodName(parameter_list) (return_value_list) { ... }
+*/
+
+type TwoInts struct {
+ a int
+ b int
+}
+
+func (tn *TwoInts) String() string {
+ return "(" + strconv.Itoa(tn.a) + "/" + strconv.Itoa(tn.b) + ")"
+}
+
+func (tn *TwoInts) AddThem() int {
+ return tn.a + tn.b
+}
+
+func (tn *TwoInts) AddToParam(param int) int {
+ return tn.a + tn.b + param
+}
+
+type B struct {
+ thing int
+}
+
+func (b *B) change() { b.thing = 1 }
+
+func (b B) write() string {
+ b.thing = 2
+ return fmt.Sprint(b)
+}
+
+type List []int
+
+func (l List) Len() int { return len(l) }
+func (l *List) Append(val int) { *l = append(*l, val) }
+
+type Engine interface {
+ Start()
+ Stop()
+}
+
+type Car struct {
+ Engine
+}
+
+func (c *Car) GoToWorkIn() {
+ // get in car
+ c.Start()
+ // drive to work
+ c.Stop()
+ // get out of car
+}
+
+type Point struct {
+ x, y float64
+}
+
+type NamedPoint struct {
+ Point
+ name string
+}
+
+func (p *Point) Abs() float64 {
+ return math.Sqrt(p.x*p.x + p.y*p.y)
+}
+
+func Tt4() {
+ Trace("tt_practice4#Tt4()")
+ defer Untrace("tt_practice4#Tt4()")
+
+ var ti *TwoInts = new(TwoInts)
+ ti.a = 1
+ ti.b = 2
+
+ fmt.Printf("AddThem: %s ", strconv.Itoa(ti.AddThem()))
+ fmt.Printf("AddToParam: %s ", strconv.Itoa(ti.AddToParam(3)))
+ fmt.Printf("toString: %s ", ti.String())
+ fmt.Println()
+
+ //change()ๆฅๅไธไธชๆๅ B ็ๆ้๏ผๅนถๆนๅๅฎๅ
้จ็ๆๅ๏ผwrite() ้่ฟๆท่ดๆฅๅ B ็ๅผๅนถๅช่พๅบ B ็ๅ
ๅฎนใ
+ var b1 B // b1ๆฏๅผ
+ b1.change()
+ fmt.Println(b1.write())
+
+ b2 := new(B) // b2ๆฏๆ้
+ b2.change()
+ fmt.Println(b2.write())
+ fmt.Println()
+
+ // ๅผ
+ var lst List
+ lst.Append(1)
+ fmt.Printf("%v (len: %d)", lst, lst.Len()) // [1] (len: 1)
+ fmt.Println()
+
+ // ๆ้
+ plst := new(List)
+ plst.Append(2)
+ fmt.Printf("%v (len: %d)", plst, plst.Len()) // &[2] (len: 1)
+ fmt.Println()
+
+ //้่็ฑปๅ
+ n := &NamedPoint{Point{3, 4}, "Pythagoras"}
+ fmt.Println(n.Abs()) // ๆๅฐ5
+}
diff --git a/internal/app/tt_practice/tt_practice5.go b/internal/app/tt_practice/tt_practice5.go
new file mode 100644
index 00000000..33fce445
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice5.go
@@ -0,0 +1,111 @@
+package tt_practice
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+)
+
+type NotknownType struct {
+ s1, s2, s3 string
+}
+
+func (n NotknownType) String() string {
+ return n.s1 + " - " + n.s2 + " - " + n.s3
+}
+
+//TODO variable to investigate:
+var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}
+
+type T struct {
+ A int
+ B string
+}
+
+/**
+reflect & io
+*/
+func Tt5() {
+ Trace("tt_practice5#Tt5()")
+ defer Untrace("tt_practice5#Tt5()")
+
+ //reflect basic type
+ var x float64 = 3.4
+ v := reflect.ValueOf(x)
+ // setting a value:
+ // v.SetFloat(3.1415) // Error: will panic: reflect.Value.SetFloat using unaddressable value
+ fmt.Println("settability of v:", v.CanSet())
+
+ v = reflect.ValueOf(&x) // Note: take the address of x.
+ fmt.Println("type of v:", v.Type())
+ fmt.Println("settability of v:", v.CanSet())
+
+ v = v.Elem()
+ fmt.Println("The Elem of v is: ", v)
+ fmt.Println("settability of v:", v.CanSet())
+
+ v.SetFloat(3.1415) // this works!
+ fmt.Println(v.Interface())
+ fmt.Println(v)
+
+ //reflect struct
+ t := T{23, "skidoo"}
+ //reflect.ValueOf(&t).Elem()
+ s := reflect.ValueOf(&t).Elem()
+ typeOfT := s.Type()
+ for i := 0; i < s.NumField(); i++ {
+ f := s.Field(i)
+ fmt.Printf("%d: %s %s = %v\n", i, typeOfT.Field(i).Name, f.Type(), f.Interface())
+ }
+ s.Field(0).SetInt(77)
+ s.Field(1).SetString("Sunset Strip")
+ fmt.Println("t is now", t)
+
+ inputFile, inputError := os.Open("internal/README.md")
+ if inputError != nil {
+ fmt.Printf("An error occurred on opening the inputfile\n" +
+ "Does the file exist?\n" +
+ "Have you got acces to it?\n")
+ return // exit the function on error
+ }
+ fmt.Println(inputFile)
+ //t_bufio(inputFile)
+ //cat(inputFile)
+
+}
+
+func t_bufio(f *os.File) {
+ defer f.Close()
+ inputReader := bufio.NewReader(f)
+ for {
+ inputString, readerError := inputReader.ReadString('\n')
+ fmt.Printf("The input was: %s", inputString)
+ if readerError == io.EOF {
+ return
+ }
+ }
+}
+
+/**
+read file by slice
+*/
+func cat(f *os.File) {
+ defer f.Close()
+ const NBUF = 512
+ var buf [NBUF]byte
+ for {
+ switch nr, err := f.Read(buf[:]); true {
+ case nr < 0:
+ fmt.Fprintf(os.Stderr, "cat: error reading: %s\n", err.Error())
+ os.Exit(1)
+ case nr == 0: // EOF
+ return
+ case nr > 0:
+ if nw, ew := os.Stdout.Write(buf[0:nr]); nw != nr {
+ fmt.Fprintf(os.Stderr, "cat: error writing: %s\n", ew.Error())
+ }
+ }
+ }
+}
diff --git a/internal/app/tt_practice/tt_practice6.go b/internal/app/tt_practice/tt_practice6.go
new file mode 100644
index 00000000..0b7d3e79
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice6.go
@@ -0,0 +1,99 @@
+package tt_practice
+
+import (
+ "fmt"
+ "strconv"
+ "time"
+)
+
+func t_timer() {
+ tick := time.Tick(1e8)
+ boom := time.After(5e8)
+ for {
+ select {
+ case <-tick:
+ fmt.Println("tick.")
+ case <-boom:
+ fmt.Println("BOOM!")
+ default:
+ fmt.Println(" .")
+ time.Sleep(5e7)
+ }
+ }
+}
+
+func sendData(ch chan string) {
+ ch <- "Washington"
+ ch <- "Tripoli"
+ ch <- "London"
+ ch <- "Beijing"
+ ch <- "Tokyo"
+ close(ch)
+}
+
+func getData(ch chan string) {
+ //ๅคๆญchannelๆฏๅฆ้ปๅก
+ for input := range ch {
+ fmt.Printf("%s ", input)
+ }
+
+ //for {
+ // //ๅคๆญchannelๆฏๅฆ้ปๅก
+ // input, open := <-ch
+ // if !open {
+ // break
+ // }
+ // fmt.Printf("%s ", input)
+ //}
+}
+
+func suck(ch1, ch2 chan int) {
+ for {
+ select {
+ //ไฟกๆฏๆ็
ง็ฎญๅคด็ๆนๅๆตๅจ
+ case v := <-ch1:
+ fmt.Printf(strconv.Itoa(v))
+ case v := <-ch2:
+ fmt.Printf(strconv.Itoa(v))
+ }
+ }
+}
+
+/**
+goroutine
+*/
+func Tt6() {
+ Trace("tt_practice6#Tt6()")
+ defer Untrace("tt_practice6#Tt6()")
+
+ fmt.Println("In app()")
+ go LongWait()
+ go ShortWait()
+ fmt.Println("About to sleep in app()")
+ // sleep works with a Duration in nanoseconds (ns) !
+ time.Sleep(1e9)
+ fmt.Println("At the end of app()")
+
+ //basic channel
+ //buf_ch1 := make(chan string, buf)
+ ch := make(chan string, 2)
+ go sendData(ch)
+ go getData(ch)
+ time.Sleep(1e9)
+ fmt.Println()
+
+ //ๆ 2 ไธช้้ ch1 ๅ ch2๏ผไธไธชๅ็จ pump1()ใpump2() ๅ suck()ใ
+ //่ฟๆฏไธไธชๅ
ธๅ็็ไบง่
ๆถ่ดน่
ๆจกๅผใๅจๆ ้ๅพช็ฏไธญ๏ผch1 ๅ ch2 ้่ฟ pump1() ๅ pump2() ๅกซๅ
ๆดๆฐ๏ผ
+ //suck() ไนๆฏๅจๆ ้ๅพช็ฏไธญ่ฝฎ่ฏข่พๅ
ฅ็๏ผ
+ //้่ฟ select ่ฏญๅฅ่ทๅ ch1 ๅ ch2 ็ๆดๆฐๅนถ่พๅบใ
+ //้ๆฉๅชไธไธช case ๅๅณไบๅชไธไธช้้ๆถๅฐไบไฟกๆฏใ็จๅบๅจ app ๆง่ก 1 ็งๅ็ปๆใ
+ ch1 := make(chan int)
+ ch2 := make(chan int)
+ go Pump1(ch1)
+ defer close(ch1)
+ go Pump2(ch2)
+ defer close(ch2)
+ go suck(ch1, ch2)
+ time.Sleep(1e8)
+
+}
diff --git a/internal/app/tt_practice/tt_practice7.go b/internal/app/tt_practice/tt_practice7.go
new file mode 100644
index 00000000..c33807cc
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice7.go
@@ -0,0 +1,144 @@
+package tt_practice
+
+import (
+ "fmt"
+ "runtime"
+ "strconv"
+ "sync"
+)
+
+type Person2 struct {
+ Name string
+ salary float64
+ chF chan func()
+}
+
+func NewPerson2(name string, salary float64) *Person2 {
+ p := &Person2{name, salary, make(chan func())}
+ go p.backend()
+ return p
+}
+
+func (p *Person2) backend() {
+ for f := range p.chF {
+ f()
+ }
+}
+
+// Set salary.
+func (p *Person2) SetSalary(sal float64) {
+ p.chF <- func() { p.salary = sal }
+}
+
+// Retrieve salary.
+func (p *Person2) Salary() float64 {
+ fChan := make(chan float64)
+ p.chF <- func() { fChan <- p.salary }
+ return <-fChan
+}
+
+func (p *Person2) String() string {
+ return "Person2 - name is: " + p.Name + " - salary is: " + strconv.FormatFloat(p.Salary(), 'f', 2, 64)
+}
+
+type Task struct {
+ tt string
+ // some state
+}
+type Pool struct {
+ Mu sync.Mutex
+ Tasks []*Task
+}
+
+func Worker1(pool *Pool) {
+ for {
+ pool.Mu.Lock()
+ // begin critical section:
+ task := pool.Tasks[0] // take the first task
+ pool.Tasks = pool.Tasks[1:] // update the pool of tasks
+ // end critical section
+ pool.Mu.Unlock()
+ //process(task)
+ fmt.Printf(task.tt)
+ }
+}
+
+func Worker2(in, out chan *Task) {
+ for {
+ t := <-in
+ //process(t)
+ fmt.Printf(t.tt)
+ out <- t
+ }
+}
+
+func f(left, right chan int) { left <- 1 + <-right }
+
+var resume chan int
+
+/**
+ๅชๅจไฝ ้่ฆๆถ่ฟ่กๆฑๅผ๏ผๅๆถไฟ็็ธๅ
ณๅ้่ตๆบ๏ผๅ
ๅญๅ cpu๏ผ๏ผ่ฟๆฏไธ้กนๅจ้่ฆๆถๅฏน่กจ่พพๅผ่ฟ่กๆฑๅผ็ๆๆฏ
+้้่ขซๅฝๅไธบyieldๅresume๏ผ่ฟไบ่ฏ็ปๅธธๅจๅ็จไปฃ็ ไธญไฝฟ็จ
+*/
+func integers() chan int {
+ yield := make(chan int)
+ count := 0
+ go func() {
+ for {
+ yield <- count
+ count++
+ }
+ }()
+ return yield
+}
+
+func generateInteger() int {
+ return <-resume
+}
+
+type EvalFunc func(Any) (Any, Any)
+
+/**
+- ไฝฟ็จ้็ๆ
ๆฏ๏ผ
+ - ่ฎฟ้ฎๅ
ฑไบซๆฐๆฎ็ปๆไธญ็็ผๅญไฟกๆฏ
+ - ไฟๅญๅบ็จ็จๅบไธไธๆๅ็ถๆไฟกๆฏๆฐๆฎ
+- ไฝฟ็จ้้็ๆ
ๆฏ๏ผ
+ - ไธๅผๆญฅๆไฝ็็ปๆ่ฟ่กไบคไบ
+ - ๅๅไปปๅก
+ - ไผ ้ๆฐๆฎๆๆๆ
+*/
+func Tt7() {
+ runtime.GOMAXPROCS(8)
+
+ //channel ๅนถๅ่ฎฟ้ฎๅฏน่ฑก
+ bs := NewPerson2("Smith Bill", 2500.5)
+ fmt.Println(bs)
+ bs.SetSalary(4000.25)
+ fmt.Println("Salary changed:")
+ fmt.Println(bs)
+
+ //pending, done := make(chan *Task), make(chan *Task)
+ //go sendWork(pending) // put tasks with work on the channel
+ //for i := 0; i < N; i++ { // start N goroutines to do work
+ // go Worker(pending, done)
+ //}
+ //consumeWork(done) // continue with the processed tasks
+
+ //้พๅผgoroutine
+ leftmost := make(chan int)
+ var left, right chan int = nil, leftmost
+ for i := 0; i < 100; i++ {
+ left, right = right, make(chan int)
+ go f(left, right)
+ }
+ right <- 0 // bang!
+ x := <-leftmost // wait for completion
+ fmt.Println(x) // 100000, ongeveer 1,5 s
+
+ //lazy generator
+ resume = integers()
+ fmt.Println(generateInteger()) //=> 0
+ fmt.Println(generateInteger()) //=> 1
+ fmt.Println(generateInteger()) //=> 2
+
+}
diff --git a/internal/app/tt_practice/tt_practice8.go b/internal/app/tt_practice/tt_practice8.go
new file mode 100644
index 00000000..aba76b05
--- /dev/null
+++ b/internal/app/tt_practice/tt_practice8.go
@@ -0,0 +1,63 @@
+package tt_practice
+
+import "fmt"
+
+type Request struct {
+ a, b int
+ replyc chan int // reply channel inside the Request
+}
+
+type binOp func(a, b int) int
+
+func run(op binOp, req *Request) {
+ req.replyc <- op(req.a, req.b)
+}
+
+func (r *Request) String() string {
+ return fmt.Sprintf("%d+%d=%d", r.a, r.b, <-r.replyc)
+}
+
+func server(op binOp, service chan *Request, quit chan bool) {
+ for {
+ select {
+ case req := <-service:
+ go run(op, req)
+ case <-quit:
+ return // stop infinite loop
+ }
+ }
+}
+
+func startServer(op binOp) (service chan *Request, quit chan bool) {
+ service = make(chan *Request)
+ quit = make(chan bool)
+ go server(op, service, quit)
+ return service, quit
+}
+
+/* output:
+3+4=7 150+250=400
+done
+*/
+func Tt8() {
+
+ //func(a, b int) int { return a + b }
+
+ blindFunc := func(a, b int) int {
+ return a + b
+ }
+
+ adder, quit := startServer(blindFunc)
+ // make requests:
+ req1 := &Request{3, 4, make(chan int)}
+ req2 := &Request{150, 250, make(chan int)}
+ // send requests on the service channel
+ adder <- req1
+ adder <- req2
+ // ask for the results: ( method String() is called )
+ fmt.Println(req1, req2)
+ // shutdown server:
+ quit <- true
+ fmt.Print("done")
+
+}
diff --git a/internal/pkg/_your_private_lib_/.keep b/internal/pkg/_your_private_lib_/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/internal/pkg/etcd_wrapper/etcdWrapper.go b/internal/pkg/etcd_wrapper/etcdWrapper.go
new file mode 100644
index 00000000..0273e33a
--- /dev/null
+++ b/internal/pkg/etcd_wrapper/etcdWrapper.go
@@ -0,0 +1,56 @@
+package etcdwrapper
+
+import (
+ "sync"
+ "time"
+
+ etcd "github.com/coreos/etcd/clientv3"
+ "go.uber.org/zap"
+)
+
+var (
+ once sync.Once
+ EtcdClient *etcd.Client
+ EtcdKV etcd.KV
+
+ etcdEndpoints = []string{"8.210.134.212:2379"}
+ //etcdUsername = "tt"
+ //etcdPassword = "tt"
+ etcdDialTimeout = 5 * time.Second
+
+ zapDevConfig = zap.NewDevelopmentConfig()
+)
+
+func init() {
+ InitEtcdClient()
+}
+
+func InitEtcdClient() *etcd.Client {
+
+ EtcdClient, err := etcd.New(etcd.Config{
+ Endpoints: etcdEndpoints,
+ DialTimeout: etcdDialTimeout,
+ //Username: etcdUsername,
+ //Password: etcdPassword,
+ LogConfig: &zapDevConfig,
+ })
+
+ if err != nil {
+ zap.S().Errorw("etcd init error")
+ }
+
+ EtcdKV = etcd.NewKV(EtcdClient)
+ zap.S().Info("etcd init succeed")
+ return EtcdClient
+}
+
+func GetEtcdKv() etcd.KV {
+ return etcd.NewKV(GetEtcdClient())
+}
+
+func GetEtcdClient() *etcd.Client {
+ once.Do(func() {
+ EtcdClient = InitEtcdClient()
+ })
+ return EtcdClient
+}
diff --git a/internal/pkg/k8s_wrapper/k8sWrapper.go b/internal/pkg/k8s_wrapper/k8sWrapper.go
new file mode 100644
index 00000000..4044795f
--- /dev/null
+++ b/internal/pkg/k8s_wrapper/k8sWrapper.go
@@ -0,0 +1,55 @@
+package k8swrapper
+
+import (
+ "path/filepath"
+
+ "github.com/mitchellh/go-homedir"
+ "go.uber.org/zap"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/tools/clientcmd"
+)
+
+var (
+ K8sClient *kubernetes.Clientset
+ K8sConfig *rest.Config
+)
+
+func init() {
+ InitK8sClient()
+}
+
+func InitK8sClient() *kubernetes.Clientset {
+ K8sConfig = GetK8sConfig()
+ K8sClient, err := kubernetes.NewForConfig(K8sConfig)
+ if err != nil {
+ panic(err.Error())
+ }
+
+ return K8sClient
+
+}
+
+//GetK8sConfig
+func GetK8sConfig() *rest.Config {
+ kubeconfig := GetK8sConfigPath()
+
+ k8sConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
+ if err != nil {
+ zap.S().Errorf("k8s client init error %w", err)
+ panic(err.Error())
+ }
+ return k8sConfig
+}
+
+//GetK8sConfigPath
+func GetK8sConfigPath() string {
+
+ if home, err := homedir.Dir(); err != nil {
+ zap.S().Errorf("k8s client init error %w", err)
+ panic(err.Error())
+ } else {
+ return filepath.Join(home, ".kube", "config")
+ }
+
+}
diff --git a/internal/pkg/nuclio_wrapper/nuclioWrapper.go b/internal/pkg/nuclio_wrapper/nuclioWrapper.go
new file mode 100644
index 00000000..6a9c5afe
--- /dev/null
+++ b/internal/pkg/nuclio_wrapper/nuclioWrapper.go
@@ -0,0 +1,93 @@
+package nucliowrapper
+
+import (
+ "os"
+ "sync"
+
+ "github.com/nuclio/nuclio/pkg/containerimagebuilderpusher"
+ "github.com/nuclio/nuclio/pkg/platform"
+ "github.com/nuclio/nuclio/pkg/platform/config"
+ "github.com/nuclio/nuclio/pkg/platform/factory"
+ nucliozap "github.com/nuclio/zap"
+
+ k8swrapper "github.com/Slahser/coup-de-grace/internal/pkg/k8s_wrapper"
+ //nucliov1beta1 "github.com/Slahser/coup-de-grace/third_party/nuclio/pkg/platform/kube/client/clientset/versioned/typed/nuclio.io/v1beta1"
+
+ nucliov1beta1 "github.com/nuclio/nuclio/pkg/platform/kube/client/clientset/versioned/typed/nuclio.io/v1beta1"
+ "go.uber.org/zap"
+)
+
+var (
+ once sync.Once
+ NuclioClient *nucliov1beta1.NuclioV1beta1Client
+ NuclioPlatform platform.Platform
+ NuclioPlayground = "nuclio-playground"
+)
+
+func init() {
+ InitNuclioClient()
+ InitNuclioPlatform()
+}
+
+func InitNuclioClient() *nucliov1beta1.NuclioV1beta1Client {
+ NuclioClient = nucliov1beta1.NewForConfigOrDie(k8swrapper.K8sConfig)
+
+ zap.S().Info("nuclio client init succeed")
+
+ return NuclioClient
+}
+
+func InitNuclioPlatform() platform.Platform {
+
+ nuclioZapLogger, _ := nucliozap.NewNuclioZap("name", "console", nil, os.Stdout, os.Stdout, nucliozap.DebugLevel)
+
+ NuclioPlatform, err := factory.CreatePlatform(nuclioZapLogger,
+ "kube",
+ &config.Configuration{
+ KubeconfigPath: k8swrapper.GetK8sConfigPath(),
+ ContainerBuilderConfiguration: containerimagebuilderpusher.ContainerBuilderConfiguration{
+ Kind: "docker",
+ BusyBoxImage: "",
+ KanikoImage: "",
+ KanikoImagePullPolicy: "",
+ JobPrefix: "",
+ DefaultRegistryCredentialsSecretName: "",
+ DefaultBaseRegistryURL: "",
+ DefaultOnbuildRegistryURL: "",
+ CacheRepo: "",
+ InsecurePushRegistry: false,
+ InsecurePullRegistry: false,
+ },
+ },
+ NuclioPlayground)
+
+ if err != nil {
+ zap.S().Fatalf("init nuclio platform error: %v", err)
+ }
+
+ return NuclioPlatform
+}
+
+func Functions() nucliov1beta1.NuclioFunctionInterface {
+ return NuclioClient.NuclioFunctions(NuclioPlayground)
+}
+
+func Projects() nucliov1beta1.NuclioProjectInterface {
+ return NuclioClient.NuclioProjects(NuclioPlayground)
+}
+
+func FunctionEvents() nucliov1beta1.NuclioFunctionEventInterface {
+ return NuclioClient.NuclioFunctionEvents(NuclioPlayground)
+}
+
+func GetNuclioClient() *nucliov1beta1.NuclioV1beta1Client {
+ once.Do(func() {
+ NuclioClient = InitNuclioClient()
+ })
+ return NuclioClient
+
+}
+
+func Tt() {
+ NuclioPlatform.CreateFunction(nil)
+}
diff --git a/internal/pkg/opkg/init.go b/internal/pkg/opkg/init.go
new file mode 100644
index 00000000..b8ffc738
--- /dev/null
+++ b/internal/pkg/opkg/init.go
@@ -0,0 +1,13 @@
+package opkg
+
+import "flag"
+
+var (
+ fVerbose bool
+ fVersion bool
+)
+
+func init() {
+ flag.BoolVar(&fVerbose, "v", false, "Do not compact consecutive bytes of fields")
+ flag.BoolVar(&fVersion, "version", false, "Print version and exit")
+}
diff --git a/internal/pkg/tpkg/init.go b/internal/pkg/tpkg/init.go
new file mode 100644
index 00000000..020f0874
--- /dev/null
+++ b/internal/pkg/tpkg/init.go
@@ -0,0 +1,20 @@
+package tpkg
+
+import (
+ "flag"
+ "math"
+ "runtime"
+)
+
+var (
+ Pi float64
+)
+
+func init() {
+ Pi = 4 * math.Atan(1) // init() function computes Pi
+
+ var numCores = flag.Int("n", 2, "number of CPU cores to use")
+
+ flag.Parse()
+ runtime.GOMAXPROCS(*numCores)
+}
diff --git a/internal/pkg/traefik_wrapper/traefikWrapper.go b/internal/pkg/traefik_wrapper/traefikWrapper.go
new file mode 100644
index 00000000..68d081e7
--- /dev/null
+++ b/internal/pkg/traefik_wrapper/traefikWrapper.go
@@ -0,0 +1,52 @@
+package traefikwrapper
+
+import (
+ "sync"
+
+ k8swrapper "github.com/Slahser/coup-de-grace/internal/pkg/k8s_wrapper"
+ "go.uber.org/zap"
+
+ traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1"
+)
+
+var (
+ once sync.Once
+ TraefikClient *traefikv1alpha1.TraefikV1alpha1Client
+
+ TraefikPlayground = "traefik-playground"
+)
+
+func init() {
+ InitTraefikClient()
+}
+
+func InitTraefikClient() *traefikv1alpha1.TraefikV1alpha1Client {
+
+ TraefikClient = traefikv1alpha1.NewForConfigOrDie(k8swrapper.K8sConfig)
+
+ zap.S().Info("faketraefikv1alpha1 client init error")
+
+ return TraefikClient
+
+}
+
+func Middlewares() traefikv1alpha1.MiddlewareInterface {
+ return TraefikClient.Middlewares(TraefikPlayground)
+}
+
+func IngressRoutes() traefikv1alpha1.IngressRouteInterface {
+ return TraefikClient.IngressRoutes(TraefikPlayground)
+}
+
+func TraefikServices() traefikv1alpha1.TraefikServiceInterface {
+ return TraefikClient.TraefikServices(TraefikPlayground)
+}
+
+func GetTraefikClient() *traefikv1alpha1.TraefikV1alpha1Client {
+
+ once.Do(func() {
+ TraefikClient = InitTraefikClient()
+ })
+ return TraefikClient
+
+}
diff --git a/internal/pkg/traefik_wrapper/traefiksvcfactory/aggrTraefikServiceFactory.go b/internal/pkg/traefik_wrapper/traefiksvcfactory/aggrTraefikServiceFactory.go
new file mode 100644
index 00000000..d8131b20
--- /dev/null
+++ b/internal/pkg/traefik_wrapper/traefiksvcfactory/aggrTraefikServiceFactory.go
@@ -0,0 +1,60 @@
+package traefiksvcfactory
+
+import (
+ traefikwrapper "github.com/Slahser/coup-de-grace/internal/pkg/traefik_wrapper"
+ traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
+ k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func init() {
+ Register("aggr", &aggrTraefikServiceFactory{})
+}
+
+// testDriverFactory implements the traefiksvcfactory.StorageDriverFactory interface.
+type aggrTraefikServiceFactory struct{}
+
+func (factory *aggrTraefikServiceFactory) Create(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+ return NewAggrFromParameters(parameters)
+}
+
+func NewAggrFromParameters(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+ return &traefikv1alpha1.TraefikService{
+ TypeMeta: k8smetav1.TypeMeta{
+ Kind: "TraefikService",
+ APIVersion: "traefik.containo.us/v1alpha1",
+ },
+ ObjectMeta: k8smetav1.ObjectMeta{
+ Name: "aggr-svc",
+ Namespace: traefikwrapper.TraefikPlayground,
+ Labels: map[string]string{
+ "type": "aggr",
+ "org": "",
+ "project": "",
+ "env": "",
+ },
+ Annotations: nil,
+ },
+ Spec: traefikv1alpha1.ServiceSpec{
+ Weighted: &traefikv1alpha1.WeightedRoundRobin{
+ Services: []traefikv1alpha1.Service{
+ {
+ LoadBalancerSpec: traefikv1alpha1.LoadBalancerSpec{
+ Name: "self-hosted-svc",
+ Kind: "TraefikService",
+ Namespace: traefikwrapper.TraefikPlayground,
+ Weight: nil,
+ },
+ },
+ {
+ LoadBalancerSpec: traefikv1alpha1.LoadBalancerSpec{
+ Name: "cloud-hosted-svc",
+ Kind: "TraefikService",
+ Namespace: traefikwrapper.TraefikPlayground,
+ Weight: nil,
+ },
+ },
+ },
+ },
+ },
+ }, nil
+}
diff --git a/internal/pkg/traefik_wrapper/traefiksvcfactory/cloudHostedTraefikServiceFactory.go b/internal/pkg/traefik_wrapper/traefiksvcfactory/cloudHostedTraefikServiceFactory.go
new file mode 100644
index 00000000..97350ad9
--- /dev/null
+++ b/internal/pkg/traefik_wrapper/traefiksvcfactory/cloudHostedTraefikServiceFactory.go
@@ -0,0 +1,48 @@
+package traefiksvcfactory
+
+import (
+ "fmt"
+ traefikwrapper "github.com/Slahser/coup-de-grace/internal/pkg/traefik_wrapper"
+ traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
+ k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func init() {
+ Register("cloudhosted", &cloudHostedTraefikServiceFactory{})
+}
+
+// testDriverFactory implements the traefiksvcfactory.StorageDriverFactory interface.
+type cloudHostedTraefikServiceFactory struct{}
+
+func (factory *cloudHostedTraefikServiceFactory) Create(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+
+ return NewCloudHostedFromParameters(parameters)
+}
+
+func NewCloudHostedFromParameters(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+
+ tt := parameters["yy"]
+ if tt == nil || fmt.Sprint(tt) == "" {
+ return nil, fmt.Errorf("no region parameter provided")
+ }
+ ttStr := fmt.Sprint(tt)
+ print(ttStr)
+
+ return &traefikv1alpha1.TraefikService{
+ TypeMeta: k8smetav1.TypeMeta{
+ Kind: "TraefikService",
+ APIVersion: "traefik.containo.us/v1alpha1",
+ },
+ ObjectMeta: k8smetav1.ObjectMeta{
+ Name: "gen-cloud-hosted-svc",
+ Namespace: traefikwrapper.TraefikPlayground,
+ Labels: map[string]string{
+ "type": "cloud-hosted",
+ "org": "ttorg",
+ "project": "ttpro",
+ "env": "ttenv",
+ },
+ Annotations: nil,
+ },
+ }, nil
+}
diff --git a/internal/pkg/traefik_wrapper/traefiksvcfactory/selfHostedTraefikServiceFactory.go b/internal/pkg/traefik_wrapper/traefiksvcfactory/selfHostedTraefikServiceFactory.go
new file mode 100644
index 00000000..427ff38d
--- /dev/null
+++ b/internal/pkg/traefik_wrapper/traefiksvcfactory/selfHostedTraefikServiceFactory.go
@@ -0,0 +1,57 @@
+package traefiksvcfactory
+
+import (
+ nucliowrapper "github.com/Slahser/coup-de-grace/internal/pkg/nuclio_wrapper"
+ traefikwrapper "github.com/Slahser/coup-de-grace/internal/pkg/traefik_wrapper"
+ traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
+ k8smetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+const svcType = "selfhosted"
+
+func init() {
+ Register(svcType, &selfHostedTraefikServiceFactory{})
+}
+
+// testDriverFactory implements the traefiksvcfactory.StorageDriverFactory interface.
+type selfHostedTraefikServiceFactory struct{}
+
+func (factory *selfHostedTraefikServiceFactory) Create(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+ return NewSelfHostedFromParameters(parameters)
+}
+
+func NewSelfHostedFromParameters(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+ return &traefikv1alpha1.TraefikService{
+ TypeMeta: k8smetav1.TypeMeta{
+ Kind: "TraefikService",
+ APIVersion: "traefik.containo.us/v1alpha1",
+ },
+ ObjectMeta: k8smetav1.ObjectMeta{
+ Name: "gen-self-hosted-svc",
+ Namespace: traefikwrapper.TraefikPlayground,
+ Labels: map[string]string{
+ "type": "self-hosted",
+ "org": "ttorg",
+ "project": "ttpro",
+ "env": "ttenv",
+ },
+ Annotations: nil,
+ },
+ Spec: traefikv1alpha1.ServiceSpec{
+ Weighted: &traefikv1alpha1.WeightedRoundRobin{
+ Services: []traefikv1alpha1.Service{
+ {
+ LoadBalancerSpec: traefikv1alpha1.LoadBalancerSpec{
+ Name: "",
+ Kind: "Service",
+ Namespace: nucliowrapper.NuclioPlayground,
+ Port: 80,
+ Scheme: "http",
+ Weight: nil,
+ },
+ },
+ },
+ },
+ },
+ }, nil
+}
diff --git a/internal/pkg/traefik_wrapper/traefiksvcfactory/traefikServiceFactory.go b/internal/pkg/traefik_wrapper/traefiksvcfactory/traefikServiceFactory.go
new file mode 100644
index 00000000..2ca3b6f5
--- /dev/null
+++ b/internal/pkg/traefik_wrapper/traefiksvcfactory/traefikServiceFactory.go
@@ -0,0 +1,43 @@
+package traefiksvcfactory
+
+import (
+ "fmt"
+ traefikv1alpha1 "github.com/containous/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
+ "github.com/go-errors/errors"
+)
+
+const (
+ SELF_HOSTED = "selfhosted"
+ CLOUD_HOSTED = "cloudhosted"
+ AGGR = "aggr"
+)
+
+var svcFactories = make(map[string]TraefikServiceFactory)
+
+/**
+registry/storage/driver/traefiksvcfactory/traefiksvcfactory.go:22
+registry/storage/driver/s3-aws/s3.go:171
+*/
+type TraefikServiceFactory interface {
+ Create(parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error)
+}
+
+func Register(name string, factory TraefikServiceFactory) {
+ if factory == nil {
+ panic("Must not provide nil TraefikServiceFactory")
+ }
+ _, registered := svcFactories[name]
+ if registered {
+ panic(fmt.Sprintf("TraefikServiceFactory named %s already registered", name))
+ }
+
+ svcFactories[name] = factory
+}
+
+func Create(name string, parameters map[string]interface{}) (*traefikv1alpha1.TraefikService, error) {
+ svcFactory, ok := svcFactories[name]
+ if !ok {
+ return nil, errors.Errorf(name)
+ }
+ return svcFactory.Create(parameters)
+}
diff --git a/internal/tt/funcs.go b/internal/tt/funcs.go
new file mode 100644
index 00000000..3274f279
--- /dev/null
+++ b/internal/tt/funcs.go
@@ -0,0 +1,9 @@
+package tt
+
+func SayCode() string {
+ return "code"
+}
+
+func SayCoverage() string {
+ return "coverage"
+}
\ No newline at end of file
diff --git a/internal/tt/funcs2.go b/internal/tt/funcs2.go
new file mode 100644
index 00000000..b5cd3fa8
--- /dev/null
+++ b/internal/tt/funcs2.go
@@ -0,0 +1,5 @@
+package tt
+
+func SayCodeCoverage() string {
+ return SayCode() + " " + SayCoverage()
+}
\ No newline at end of file
diff --git a/justfile b/justfile
new file mode 100644
index 00000000..ec13fd80
--- /dev/null
+++ b/justfile
@@ -0,0 +1,91 @@
+#!/usr/bin/env just --justfile
+
+# ==================simple one======================
+
+version := "0.2.7"
+tardir := "awesomesauce-" + version
+
+alias alias_t := recipe-name
+
+# justไผๅจ่ฟ่ก็ๆญฃๅฝไปคไนๅ๏ผๅฐๆฏไธชๅฝไปคๆๅฐๅฐๆ ๅ้่ฏฏ(stderr)๏ผ่ฟๅฐฑๆฏไธบไปไนecho 'This is a recipe!'ไผ่ขซๆๅฐใ
+# just version=1 recipe-name
+recipe-name:
+ echo 'This is a recipe! with var {{tardir}}'
+
+# ่ฟๆฏไธไธชๆณจ้ ๅฝ็ถไฝ ๅฏไปฅไฝฟ็จ@ไฝไธบ่กๅผๅคด๏ผ่ฟๆ ทไผๆๅถๆๅฐใ
+another-recipe:
+ @echo 'This is another recipe.'
+
+# ่ฝฌไน
+braces:
+ echo '{{'I {{LOVE}} curly braces!'}}'
+
+system-info:
+ @echo "This is an {{arch()}} {{os()}} machine".
+
+# env_var(key) - ็จๅ็งฐkeyๆฃ็ดข็ฏๅขๅ้๏ผๅฆๆไธๅญๅจไผไธญๆญข.
+# env_var_or_default(key, default) - ็จๅ็งฐkeyๆฃ็ดข็ฏๅขๅ้๏ผๅฆๆๅฎไธๅญๅจๅ่ฟๅdefaultๅผ.
+
+# ็ฏๅขๅ้ .env
+env:
+ echo 'tt env $ENV1 '
+
+dir:
+ cd {{invocation_directory()}}; echo tt
+
+# ๆฅๆถๅๆฐ
+build target:
+ @echo 'Building {{target}}...'
+
+default := 'all'
+# ๆฅๆถๅๆฐ
+test target tests=default:
+ @echo 'Testing {{target}}:{{tests}}...'
+
+# search with "kw"
+search QUERY:
+ lynx https://www.google.com/?q={{QUERY}}
+
+# ๆกไปถ
+conditional:
+ #!/usr/bin/env sh
+ if true; then
+ echo 'True!'
+ fi
+
+# ๅพช็ฏ
+for:
+ #!/usr/bin/env sh
+ for file in `ls .`; do
+ echo $file
+ done
+
+# ้่ไธ่ๆฌ
+polyglot: _python _js _perl _sh _ruby
+# (recipes that start with `_` are hidden from --list)
+
+_python:
+ #!/usr/bin/env python3
+ print('Hello from python!')
+
+_js:
+ #!/usr/bin/env node
+ console.log('Greetings from JavaScript!')
+
+_perl:
+ #!/usr/bin/env perl
+ print "Larry Wall says Hi!\n";
+
+_sh:
+ #!/usr/bin/env sh
+ hello='Yo'
+ echo "$hello from a shell script!"
+
+_ruby:
+ #!/usr/bin/env ruby
+ puts "Hello from ruby!"
+
+# ==================complex one======================
+
+
+
diff --git a/magefile.go b/magefile.go
new file mode 100644
index 00000000..b2a0c178
--- /dev/null
+++ b/magefile.go
@@ -0,0 +1,363 @@
+// +build mage
+
+//https://magefile.org/
+//https://github.com/magefile/awesome-mage
+
+package main
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/magefile/mage/mg"
+ "github.com/magefile/mage/sh"
+)
+
+var (
+ goexe = "go"
+ docker = sh.RunCmd("docker")
+ packageName = "github.com/Slahser/coup-de-grace"
+ pkgPrefixLen = len(packageName)
+ noGitLdflags = "-X $PACKAGE/common/slahser.buildDate=$BUILD_DATE"
+ ldflags = "-X $PACKAGE/common/slahser.commitHash=$COMMIT_HASH " + noGitLdflags
+ pkgs []string
+ pkgsInit sync.Once
+)
+
+func init() {
+ if exe := os.Getenv("GOEXE"); exe != "" {
+ goexe = exe
+ }
+
+ // We want to use Go 1.11 modules even if the source lives inside GOPATH.
+ // The default is "auto".
+ _ = os.Setenv("GO111MODULE", "on")
+}
+
+// Install binary
+func Install() error {
+ return runWith(flagEnv(), goexe, "install", "-ldflags", ldflags, buildFlags(), "-tags", buildTags(), packageName)
+}
+
+// Uninstall binary
+func Uninstall() error {
+ return sh.Run(goexe, "clean", "-i", packageName)
+}
+
+// GenDocsHelper Gen docs helper
+func GenDocsHelper() error {
+ return runCmd(flagEnv(), goexe, "run", "-tags", buildTags(), "main.go", "gen", "docshelper")
+}
+
+// Check tests and linters
+func Check() {
+ if strings.Contains(runtime.Version(), "1.8") {
+ // Go 1.8 doesn't play along with go test ./... and /vendor.
+ // We could fix that, but that would take time.
+ fmt.Printf("Skip Check on %s\n", runtime.Version())
+ return
+ }
+
+ if runtime.GOARCH == "amd64" && runtime.GOOS != "darwin" {
+ mg.Deps(Test386)
+ } else {
+ fmt.Printf("Skip Test386 on %s and/or %s\n", runtime.GOARCH, runtime.GOOS)
+ }
+
+ mg.Deps(Fmt, Vet)
+
+ // don't run two tests in parallel, they saturate the CPUs anyway, and running two
+ // causes memory issues in CI.
+ mg.Deps(TestRace)
+}
+
+// Build hugo Docker container
+func Docker() error {
+ if err := docker("build", "-t", "hugo", "."); err != nil {
+ return err
+ }
+ // yes ignore errors here
+ _ = docker("rm", "-f", "hugo-build")
+ if err := docker("run", "--name", "hugo-build", "hugo ls /go/bin"); err != nil {
+ return err
+ }
+ if err := docker("cp", "hugo-build:/go/bin/hugo", "."); err != nil {
+ return err
+ }
+ return docker("rm", "hugo-build")
+}
+
+// Run tests
+func Test() error {
+ env := map[string]string{"GOFLAGS": testGoFlags()}
+ return runCmd(env, goexe, "test", "./...", buildFlags(), "-tags", buildTags())
+}
+
+// Run tests with race detector
+func TestRace() error {
+ env := map[string]string{"GOFLAGS": testGoFlags()}
+ return runCmd(env, goexe, "test", "-race", "./...", buildFlags(), "-tags", buildTags())
+}
+
+// Run tests in 32-bit mode
+// Note that we don't run with the extended tag. Currently not supported in 32 bit.
+func Test386() error {
+ env := map[string]string{"GOARCH": "386", "GOFLAGS": testGoFlags()}
+ return runCmd(env, goexe, "test", "./...")
+}
+
+// Run gofmt linter
+func Fmt() error {
+ if !isGoLatest() {
+ return nil
+ }
+ pkgs, err := currentPackages()
+ if err != nil {
+ return err
+ }
+ failed := false
+ first := true
+ for _, pkg := range pkgs {
+ files, err := filepath.Glob(filepath.Join(pkg, "*.go"))
+ if err != nil {
+ return nil
+ }
+ for _, f := range files {
+ // gofmt doesn't exit with non-zero when it finds unformatted code
+ // so we have to explicitly look for output, and if we find any, we
+ // should fail this target.
+ s, err := sh.Output("gofmt", "-l", f)
+ if err != nil {
+ fmt.Printf("ERROR: running gofmt on %q: %v\n", f, err)
+ failed = true
+ }
+ if s != "" {
+ if first {
+ fmt.Println("The following files are not gofmt'ed:")
+ first = false
+ }
+ failed = true
+ fmt.Println(s)
+ }
+ }
+ }
+ if failed {
+ return errors.New("improperly formatted go files")
+ }
+ return nil
+}
+
+// Run golint linter
+func Lint() error {
+ pkgs, err := currentPackages()
+ if err != nil {
+ return err
+ }
+ failed := false
+ for _, pkg := range pkgs {
+ // We don't actually want to fail this target if we find golint errors,
+ // so we don't pass -set_exit_status, but we still print out any failures.
+ if _, err := sh.Exec(nil, os.Stderr, nil, "golint", pkg); err != nil {
+ fmt.Printf("ERROR: running go lint on %q: %v\n", pkg, err)
+ failed = true
+ }
+ }
+ if failed {
+ return errors.New("errors running golint")
+ }
+ return nil
+}
+
+// Run go vet linter
+func Vet() error {
+ if err := sh.Run(goexe, "vet", "./..."); err != nil {
+ return fmt.Errorf("error running go vet: %v", err)
+ }
+ return nil
+}
+
+// Generates a new release. Expects the TAG environment variable to be set,
+// which will create a new tag with that name.
+func Release() (err error) {
+ releaseTag := regexp.MustCompile(`^v1\.[0-9]+\.[0-9]+$`)
+ //https://goreleaser.com/intro/
+ tag := os.Getenv("TAG")
+ if !releaseTag.MatchString(tag) {
+ return errors.New("TAG environment variable must be in semver v1.x.x format, but was " + tag)
+ }
+
+ if err := sh.RunV("git", "tag", "-a", tag, "-m", tag); err != nil {
+ return err
+ }
+ if err := sh.RunV("git", "push", "origin", tag); err != nil {
+ return err
+ }
+ defer func() {
+ if err != nil {
+ sh.RunV("git", "tag", "--delete", "$TAG")
+ sh.RunV("git", "push", "--delete", "origin", "$TAG")
+ }
+ }()
+ return sh.RunV("goreleaser")
+}
+
+// Generate test coverage report
+func TestCoverHTML() error {
+ const (
+ coverAll = "coverage-all.out"
+ cover = "coverage.out"
+ )
+ f, err := os.Create(coverAll)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ if _, err := f.Write([]byte("mode: count")); err != nil {
+ return err
+ }
+ pkgs, err := currentPackages()
+ if err != nil {
+ return err
+ }
+ for _, pkg := range pkgs {
+ if err := sh.Run(goexe, "test", "-coverprofile="+cover, "-covermode=count", pkg); err != nil {
+ return err
+ }
+ b, err := ioutil.ReadFile(cover)
+ if err != nil {
+ if os.IsNotExist(err) {
+ continue
+ }
+ return err
+ }
+ idx := bytes.Index(b, []byte{'\n'})
+ b = b[idx+1:]
+ if _, err := f.Write(b); err != nil {
+ return err
+ }
+ }
+ if err := f.Close(); err != nil {
+ return err
+ }
+ return sh.Run(goexe, "tool", "cover", "-html="+coverAll)
+}
+
+func flagEnv() map[string]string {
+ hash, _ := sh.Output("git", "rev-parse", "--short", "HEAD")
+ return map[string]string{
+ "PACKAGE": packageName,
+ "COMMIT_HASH": hash,
+ "BUILD_DATE": time.Now().Format("2006-01-02T15:04:05Z0700"),
+ }
+}
+
+func argsToStrings(v ...interface{}) []string {
+ var args []string
+ for _, arg := range v {
+ switch v := arg.(type) {
+ case string:
+ if v != "" {
+ args = append(args, v)
+ }
+ case []string:
+ if v != nil {
+ args = append(args, v...)
+ }
+ default:
+ panic("invalid type")
+ }
+ }
+
+ return args
+}
+
+func isGoLatest() bool {
+ return strings.Contains(runtime.Version(), "1.14")
+}
+
+func runCmd(env map[string]string, cmd string, args ...interface{}) error {
+ if mg.Verbose() {
+ return runWith(env, cmd, args...)
+ }
+ output, err := sh.OutputWith(env, cmd, argsToStrings(args...)...)
+ if err != nil {
+ fmt.Fprint(os.Stderr, output)
+ }
+
+ return err
+}
+
+func runWith(env map[string]string, cmd string, inArgs ...interface{}) error {
+ s := argsToStrings(inArgs...)
+ return sh.RunWith(env, cmd, s...)
+
+}
+
+func currentPackages() ([]string, error) {
+ var err error
+ pkgsInit.Do(func() {
+ var s string
+ s, err = sh.Output(goexe, "list", "./...")
+ if err != nil {
+ return
+ }
+ pkgs = strings.Split(s, "\n")
+ for i := range pkgs {
+ pkgs[i] = "." + pkgs[i][pkgPrefixLen:]
+ }
+ })
+ return pkgs, err
+}
+
+func testGoFlags() string {
+ if isCI() {
+ return ""
+ }
+
+ return "-test.short"
+}
+
+func isCI() bool {
+ return os.Getenv("CI") != ""
+}
+
+func buildFlags() []string {
+ if runtime.GOOS == "windows" {
+ return []string{"-buildmode", "exe"}
+ }
+ return nil
+}
+
+func buildTags() string {
+ // To build the extended Hugo SCSS/SASS enabled version, build with
+ // SLAHSER_BUILD_TAGS=extended mage install etc.
+ if envtags := os.Getenv("SLAHSER_BUILD_TAGS"); envtags != "" {
+ return envtags
+ }
+ return "none"
+}
+
+func xplatPath(pathParts ...string) string {
+ return filepath.Join(pathParts...)
+}
+
+func gitCommit(shortVersion bool) (string, error) {
+ args := []string{
+ "rev-parse",
+ }
+ if shortVersion {
+ args = append(args, "--short")
+ }
+ args = append(args, "HEAD")
+ val, valErr := sh.Output("git", args...)
+ return strings.TrimSpace(val), valErr
+}
diff --git a/pkg/_your_public_lib_/.keep b/pkg/_your_public_lib_/.keep
deleted file mode 100644
index e69de29b..00000000
diff --git a/pkg/edgeserver/edgeserver.go b/pkg/edgeserver/edgeserver.go
new file mode 100644
index 00000000..262c9811
--- /dev/null
+++ b/pkg/edgeserver/edgeserver.go
@@ -0,0 +1,205 @@
+package edgeserver
+
+import (
+ "fmt"
+ "net/http"
+ "time"
+
+ "github.com/fvbock/endless"
+ ginlimits "github.com/gin-contrib/size"
+ ginzap "github.com/gin-contrib/zap"
+ "github.com/gin-gonic/gin"
+ "github.com/go-errors/errors"
+ "github.com/gorilla/websocket"
+ "github.com/jinzhu/configor"
+ "github.com/natefinch/lumberjack"
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+)
+
+/**
+ๆๆไธๆฎตFC็่ชๅฎไนServer.
+
+็ๅฌๅจไปปไฝIP๏ผ0.0.0.0๏ผ็ๆๅฎ็ซฏๅฃ๏ผ็ซฏๅฃๅฏไปฅ่ฏปๅ็ฏๅขๅ้FC_SERVER_PORT๏ผ้ป่ฎคไธบ9000๏ผใ
+HTTP Server้้
็ฝฎconnection keep-aliveใ
+่ฏทๆฑ่ถ
ๆถๆถ้ด่ฎพ็ฝฎไธบ15ๅ้ไปฅไธใ
+HTTP Server้่ฆๅจ25็งๅ
ๅฏๅจๅฎๆฏใ
+*/
+var (
+ Logger *zap.Logger
+ Router *gin.Engine
+ UpGrader = websocket.Upgrader{
+ CheckOrigin: func(r *http.Request) bool {
+ return true
+ },
+ }
+
+)
+
+const (
+ ConfigPath = "./config.toml"
+ ListeningPort = ":8080"
+
+ ServerReadTimeOut=180
+ ServerWriteTimeOut=180
+ ServerMaxHeaderBytes=1 << 20
+
+ LogFile="./logs/edgeserver.log"
+ LogMaxSize = 10
+ LogMaxBackups = 5
+ LogMaxAge =30
+ LoggerName="edgeserver"
+)
+
+type EdgeServer struct {
+ Config Config
+}
+
+type Config struct {
+ Env string `required:"true"`
+ Org string `required:"true"`
+ Project string `required:"true"`
+}
+
+//Init
+func Init() *EdgeServer {
+ var Config Config
+
+ if err := configor.Load(&Config, ConfigPath); err != nil {
+ fmt.Println(errors.Errorf("parse edgeserver config.toml error %w", err))
+ }
+
+ return NewForConfigOrDie(&Config)
+}
+
+//NewForConfigOrDie
+func NewForConfigOrDie(config *Config) *EdgeServer {
+ server, err := NewForConfig(config)
+ if err != nil {
+ fmt.Println(errors.Errorf("init edgeserver error %w", err))
+ }
+ return server
+}
+
+//NewForConfig
+func NewForConfig(config *Config) (*EdgeServer, error) {
+ c := *config
+ server := &EdgeServer{c}
+ if err := server.tunning(); err != nil {
+ return nil, err
+ }
+ return server, nil
+}
+
+//Start
+func (server *EdgeServer) Start() {
+
+ endless.DefaultReadTimeOut = ServerReadTimeOut * time.Second
+ endless.DefaultWriteTimeOut = ServerWriteTimeOut * time.Second
+ endless.DefaultMaxHeaderBytes = ServerMaxHeaderBytes
+ if err := endless.ListenAndServe(ListeningPort, Router); err != nil {
+ fmt.Println(errors.Errorf("serve edgeserver error %w", err))
+ }
+}
+
+//HTTPGet
+func (server *EdgeServer) HTTPGet(path string, handlerFunc gin.HandlerFunc) {
+
+ //TODO ่ฏปetcd
+ // ๆฃๆฅetcd /dev/slahser/ttproj/edgefunc1/path/ ๆฏๅฆๅญๅจ
+
+ Router.GET(path, handlerFunc)
+ //TODO ๅๅ
ฅetcd
+ // k => /dev/slahser/ttproj/edgefunc1/path/
+ // v=> ๆๆถ็ฝฎ็ฉบ,ๆฅๅ็ไฝๆฉๅฑ
+}
+
+//HTTPPost
+func (server *EdgeServer) HTTPPost(path string, handlerFunc gin.HandlerFunc) {
+ //TODO ่ฏปetcd
+ // ๆฃๆฅetcd /dev/slahser/ttproj/edgefunc1/path/ ๆฏๅฆๅญๅจ
+
+ Router.POST(path, handlerFunc)
+
+ //TODO ๅๅ
ฅetcd
+ // k => /dev/slahser/ttproj/edgefunc1/path/
+ // v=> ๆๆถ็ฝฎ็ฉบ,ๆฅๅ็ไฝๆฉๅฑ
+}
+
+//WSGet
+func (server *EdgeServer) WSGet(path string, handlerFunc gin.HandlerFunc) {
+
+ //TODO ่ฏปetcd
+ // ๆฃๆฅetcd /dev/slahser/ttproj/edgefunc1/path/ ๆฏๅฆๅญๅจ
+
+ Router.GET(path, handlerFunc)
+
+ //TODO ๅๅ
ฅetcd
+ // k => /dev/slahser/ttproj/edgefunc1/path/
+ // v=> ๆๆถ็ฝฎ็ฉบ,ๆฅๅ็ไฝๆฉๅฑ
+}
+
+//GetWSConn
+func GetWSConn(c *gin.Context) *websocket.Conn {
+ wsConn, err := UpGrader.Upgrade(c.Writer, c.Request, nil)
+ if err != nil {
+ fmt.Println(errors.Errorf("get websocket connection error %w", err))
+ }
+ return wsConn
+}
+
+func (server *EdgeServer) tunning() error {
+
+ zap.ReplaceGlobals(InitLogger())
+
+ gin.SetMode(gin.DebugMode)
+
+ Router = gin.New()
+ Router.Use(gin.Logger())
+ Router.Use(gin.Recovery())
+ Router.Use(ginlimits.RequestSizeLimiter(10))
+ Router.Use(ginzap.Ginzap(Logger, time.RFC3339, true))
+ Router.Use(ginzap.RecoveryWithZap(Logger, true))
+ Router.NoRoute(NoRouteHandlerFunc)
+ Router.NoMethod(NoMethodHandlerFunc)
+ return nil
+}
+
+var NoRouteHandlerFunc gin.HandlerFunc = func(context *gin.Context) {
+ context.JSON(http.StatusNotFound, "NoRoute")
+}
+
+var NoMethodHandlerFunc gin.HandlerFunc = func(context *gin.Context) {
+ context.JSON(http.StatusMethodNotAllowed,"NoMethod")
+}
+
+//InitLogger
+func InitLogger() *zap.Logger {
+ writeSyncer := getLogWriter()
+ encoder := getEncoder()
+ core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
+
+ Logger = zap.New(core, zap.AddCaller())
+ Logger.Named(LoggerName)
+ return Logger
+}
+
+//getEncoder
+func getEncoder() zapcore.Encoder {
+ encoderConfig := zap.NewProductionEncoderConfig()
+ encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
+ encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
+ return zapcore.NewJSONEncoder(encoderConfig)
+}
+
+//getLogWriter
+func getLogWriter() zapcore.WriteSyncer {
+ lumberJackLogger := &lumberjack.Logger{
+ Filename: LogFile,
+ MaxSize: LogMaxSize,
+ MaxBackups: LogMaxBackups,
+ MaxAge: LogMaxAge,
+ Compress: true,
+ }
+ return zapcore.AddSync(lumberJackLogger)
+}
diff --git a/pkg/ttctl/func.go b/pkg/ttctl/func.go
new file mode 100644
index 00000000..6c8bdc96
--- /dev/null
+++ b/pkg/ttctl/func.go
@@ -0,0 +1,36 @@
+package ttctl
+
+import (
+ cobra "github.com/spf13/cobra"
+)
+
+type funcCommandeer struct {
+ cmd *cobra.Command
+ rootCommandeer *RootCommandeer
+}
+
+func newFuncCommandeer(rootCommandeer *RootCommandeer) *funcCommandeer {
+ commandeer := &funcCommandeer{
+ rootCommandeer: rootCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "func [command]",
+ Aliases: []string{"function"},
+ Short: "Operations for Tt Function.",
+ SilenceUsage: true,
+ SilenceErrors: true,
+ }
+
+ cmd.AddCommand(
+ newFuncDeployCommandeer(commandeer).cmd,
+ newFuncBuildImageCommandeer(commandeer).cmd,
+ newFuncDescribeCommandeer(commandeer).cmd,
+ newFuncDeleteCommandeer(commandeer).cmd,
+ newFuncUpdateCommandeer(commandeer).cmd,
+ )
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/funcBuildImage.go b/pkg/ttctl/funcBuildImage.go
new file mode 100644
index 00000000..5a54c096
--- /dev/null
+++ b/pkg/ttctl/funcBuildImage.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+type funcBuildImageCommandeer struct {
+ cmd *cobra.Command
+ funcCommandeer *funcCommandeer
+}
+
+func newFuncBuildImageCommandeer(funcCommandeer *funcCommandeer) *funcBuildImageCommandeer {
+ commandeer := &funcBuildImageCommandeer{
+ funcCommandeer: funcCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "build-image [-flag]",
+ Aliases: []string{"build"},
+ Short: "Build a function image.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/funcDelete.go b/pkg/ttctl/funcDelete.go
new file mode 100644
index 00000000..6d2b6fd5
--- /dev/null
+++ b/pkg/ttctl/funcDelete.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+type funcDeleteCommandeer struct {
+ cmd *cobra.Command
+ funcCommandeer *funcCommandeer
+}
+
+func newFuncDeleteCommandeer(funcCommandeer *funcCommandeer) *funcDeleteCommandeer {
+ commandeer := &funcDeleteCommandeer{
+ funcCommandeer: funcCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "delete [-flag]",
+ Aliases: []string{"remove", "uninstall"},
+ Short: "Delete a Function.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/funcDeploy.go b/pkg/ttctl/funcDeploy.go
new file mode 100644
index 00000000..fd8b0699
--- /dev/null
+++ b/pkg/ttctl/funcDeploy.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+type funcDeployCommandeer struct {
+ cmd *cobra.Command
+ funcCommandeer *funcCommandeer
+}
+
+func newFuncDeployCommandeer(funcCommandeer *funcCommandeer) *funcDeployCommandeer {
+ commandeer := &funcDeployCommandeer{
+ funcCommandeer: funcCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "deploy [-flag]",
+ Aliases: []string{"add", "install", "upload"},
+ Short: "Deploy a Function ",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/funcDescribe.go b/pkg/ttctl/funcDescribe.go
new file mode 100644
index 00000000..8652ef3b
--- /dev/null
+++ b/pkg/ttctl/funcDescribe.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+type funcDescribeCommandeer struct {
+ cmd *cobra.Command
+ funcCommandeer *funcCommandeer
+}
+
+func newFuncDescribeCommandeer(funcCommandeer *funcCommandeer) *funcDescribeCommandeer {
+ commandeer := &funcDescribeCommandeer{
+ funcCommandeer: funcCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "desc [-flag]",
+ Aliases: []string{"describe"},
+ Short: "Describe specific Function.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/funcUpdate.go b/pkg/ttctl/funcUpdate.go
new file mode 100644
index 00000000..c402ee1b
--- /dev/null
+++ b/pkg/ttctl/funcUpdate.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+)
+
+type funcUpdateCommandeer struct {
+ cmd *cobra.Command
+ funcCommandeer *funcCommandeer
+}
+
+func newFuncUpdateCommandeer(funcCommandeer *funcCommandeer) *funcUpdateCommandeer {
+ commandeer := &funcUpdateCommandeer{
+ funcCommandeer: funcCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "func",
+ Aliases: []string{"function"},
+ Short: "Update a Function.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/helper/cobra-prompt.go b/pkg/ttctl/helper/cobra-prompt.go
new file mode 100644
index 00000000..07dfab79
--- /dev/null
+++ b/pkg/ttctl/helper/cobra-prompt.go
@@ -0,0 +1,97 @@
+package cobraprompt
+
+import (
+ "os"
+ "strings"
+
+ "github.com/c-bata/go-prompt"
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+// CALLBACK_ANNOTATION
+const CALLBACK_ANNOTATION = "cobra-prompt"
+
+// CobraPrompt requires RootCmd to run
+type CobraPrompt struct {
+ // RootCmd is the start point, all its sub commands and flags will be available as suggestions
+ RootCmd *cobra.Command
+
+ // GoPromptOptions is for customize go-prompt
+ // see https://github.com/c-bata/go-prompt/blob/master/option.go
+ GoPromptOptions []prompt.Option
+
+ // DynamicSuggestionsFunc will be executed if an command has CALLBACK_ANNOTATION as an annotation. If it's included
+ // the value will be provided to the DynamicSuggestionsFunc function.
+ DynamicSuggestionsFunc func(annotation string, document prompt.Document) []prompt.Suggest
+
+ // ResetFlagsFlag will add a new persistent flag to RootCmd. This flags can be used to turn off flags value reset
+ ResetFlagsFlag bool
+}
+
+// Run will automatically generate suggestions for all cobra commands and flags defined by RootCmd
+// and execute the selected commands. Run will also reset all given flags by default, see ResetFlagsFlag
+func (co CobraPrompt) Run() {
+ co.prepare()
+ p := prompt.New(
+ func(in string) {
+ promptArgs := strings.Fields(in)
+ os.Args = append([]string{os.Args[0]}, promptArgs...)
+ co.RootCmd.Execute()
+ },
+ func(d prompt.Document) []prompt.Suggest {
+ return findSuggestions(co, d)
+ },
+ co.GoPromptOptions...,
+ )
+ p.Run()
+}
+
+func (co CobraPrompt) prepare() {
+ if co.ResetFlagsFlag {
+ co.RootCmd.PersistentFlags().BoolP("flags-no-reset", "",
+ false, "Flags will no longer reset to default value")
+ }
+}
+
+func findSuggestions(co CobraPrompt, d prompt.Document) []prompt.Suggest {
+ command := co.RootCmd
+ args := strings.Fields(d.CurrentLine())
+
+ if found, _, err := command.Find(args); err == nil {
+ command = found
+ }
+
+ var suggestions []prompt.Suggest
+ resetFlags, _ := command.Flags().GetBool("flags-no-reset")
+ addFlags := func(flag *pflag.Flag) {
+ if flag.Changed && !resetFlags {
+ flag.Value.Set(flag.DefValue)
+ }
+ if flag.Hidden {
+ return
+ }
+ if strings.HasPrefix(d.GetWordBeforeCursor(), "--") {
+ suggestions = append(suggestions, prompt.Suggest{Text: "--" + flag.Name, Description: flag.Usage})
+ } else if strings.HasPrefix(d.GetWordBeforeCursor(), "-") && flag.Shorthand != "" {
+ suggestions = append(suggestions, prompt.Suggest{Text: "-" + flag.Shorthand, Description: flag.Usage})
+ }
+ }
+
+ command.LocalFlags().VisitAll(addFlags)
+ command.InheritedFlags().VisitAll(addFlags)
+
+ if command.HasAvailableSubCommands() {
+ for _, c := range command.Commands() {
+ if !c.Hidden {
+ suggestions = append(suggestions, prompt.Suggest{Text: c.Name(), Description: c.Short})
+ }
+ }
+ }
+
+ annotation := command.Annotations[CALLBACK_ANNOTATION]
+ if co.DynamicSuggestionsFunc != nil && annotation != "" {
+ suggestions = append(suggestions, co.DynamicSuggestionsFunc(annotation, d)...)
+ }
+ return prompt.FilterHasPrefix(suggestions, d.GetWordBeforeCursor(), true)
+}
diff --git a/pkg/ttctl/ttctl.go b/pkg/ttctl/ttctl.go
new file mode 100644
index 00000000..fcfc0c45
--- /dev/null
+++ b/pkg/ttctl/ttctl.go
@@ -0,0 +1,86 @@
+package ttctl
+
+import (
+ jsoniter "github.com/json-iterator/go"
+ cobra "github.com/spf13/cobra"
+ doc "github.com/spf13/cobra/doc"
+ zap "go.uber.org/zap"
+)
+
+var (
+ json = jsoniter.ConfigCompatibleWithStandardLibrary
+)
+
+type RootCommandeer struct {
+ logger *zap.SugaredLogger
+ cmd *cobra.Command
+ verbose bool
+}
+
+func NewRootCommandeer() *RootCommandeer {
+ commandeer := &RootCommandeer{}
+
+ cmd := &cobra.Command{
+ Use: "ttctl [command]",
+ Short: "Tt terminal ui",
+ SilenceUsage: true,
+ SilenceErrors: true,
+ }
+
+ cmd.PersistentFlags().BoolVarP(&commandeer.verbose, "verbose", "v", false, "Verbose mode, show more details")
+
+ cmd.AddCommand(
+ newVersionCommandeer(commandeer).cmd,
+ newWorkspaceCommandeer(commandeer).cmd,
+ newFuncCommandeer(commandeer).cmd,
+ )
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
+
+// Execute uses os.Args to execute the command
+func (rc *RootCommandeer) Execute() error {
+ return rc.cmd.Execute()
+}
+
+// GetCmd returns the underlying cobra command
+func (rc *RootCommandeer) GetCmd() *cobra.Command {
+ return rc.cmd
+}
+
+// CreateMarkdown generates MD files in the target path
+func (rc *RootCommandeer) CreateMarkdown(path string) error {
+ return doc.GenMarkdownTree(rc.cmd, path)
+}
+
+func (rc *RootCommandeer) initialize() error {
+ var err error
+
+ rc.logger, err = rc.createLogger()
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (rc *RootCommandeer) createLogger() (*zap.SugaredLogger, error) {
+
+ var loggingConfig zap.Config
+
+ if rc.verbose {
+ loggingConfig = zap.NewDevelopmentConfig()
+ } else {
+ loggingConfig = zap.NewProductionConfig()
+ }
+
+ logger, err := loggingConfig.Build()
+ if logger != nil {
+ sugar := logger.Sugar()
+ return sugar, nil
+ } else {
+ return nil, err
+ }
+}
diff --git a/pkg/ttctl/version.go b/pkg/ttctl/version.go
new file mode 100644
index 00000000..5ea6928c
--- /dev/null
+++ b/pkg/ttctl/version.go
@@ -0,0 +1,33 @@
+package ttctl
+
+import (
+ "fmt"
+
+ cobra "github.com/spf13/cobra"
+ version "github.com/v3io/version-go"
+)
+
+type versionCommandeer struct {
+ cmd *cobra.Command
+ rootCommandeer *RootCommandeer
+}
+
+func newVersionCommandeer(rootCommandeer *RootCommandeer) *versionCommandeer {
+ commandeer := &versionCommandeer{
+ rootCommandeer: rootCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "version",
+ Aliases: []string{"ver"},
+ Short: "Display the version of the ttctl CLI",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("Client version:\n%#v", version.Get().String())
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/workspace.go b/pkg/ttctl/workspace.go
new file mode 100644
index 00000000..90a6c442
--- /dev/null
+++ b/pkg/ttctl/workspace.go
@@ -0,0 +1,40 @@
+package ttctl
+
+import (
+ cobra "github.com/spf13/cobra"
+)
+
+type workspaceCommandeer struct {
+ cmd *cobra.Command
+ rootCommandeer *RootCommandeer
+}
+
+func newWorkspaceCommandeer(rootCommandeer *RootCommandeer) *workspaceCommandeer {
+ commandeer := &workspaceCommandeer{
+ rootCommandeer: rootCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "ws [command]",
+ Aliases: []string{"workspace"},
+ Short: "Config/Switch/Show local workspace",
+ SilenceUsage: true,
+ SilenceErrors: true,
+ }
+
+ cmd.AddCommand(
+ newWorkspaceInitCommandeer(commandeer).cmd,
+ newWorkspaceShowCommandeer(commandeer).cmd,
+ newWorkspaceSwitchCommandeer(commandeer).cmd,
+ )
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
+
+type workspaceConfig struct {
+ UserId string `json:"user_id"`
+ Organization string `json:"organization"`
+ Project string `json:"project"`
+}
diff --git a/pkg/ttctl/workspaceInit.go b/pkg/ttctl/workspaceInit.go
new file mode 100644
index 00000000..d5910407
--- /dev/null
+++ b/pkg/ttctl/workspaceInit.go
@@ -0,0 +1,32 @@
+package ttctl
+
+import (
+ "fmt"
+
+ cobra "github.com/spf13/cobra"
+)
+
+type workspaceInitCommandeer struct {
+ cmd *cobra.Command
+ workspaceCommandeer *workspaceCommandeer
+}
+
+func newWorkspaceInitCommandeer(workspaceCommandeer *workspaceCommandeer) *workspaceInitCommandeer {
+ commandeer := &workspaceInitCommandeer{
+ workspaceCommandeer: workspaceCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "init",
+ Short: "Init a workspace.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("here is a promptui integration,show current worksapce user id and wizard to fetch and switch to other sorkspace.")
+ //viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttctl/workspaceShow.go b/pkg/ttctl/workspaceShow.go
new file mode 100644
index 00000000..6401a646
--- /dev/null
+++ b/pkg/ttctl/workspaceShow.go
@@ -0,0 +1,54 @@
+package ttctl
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+
+ homedir "github.com/mitchellh/go-homedir"
+ cobra "github.com/spf13/cobra"
+)
+
+type workspaceShowCommandeer struct {
+ cmd *cobra.Command
+ workspaceCommandeer *workspaceCommandeer
+}
+
+func newWorkspaceShowCommandeer(workspaceCommandeer *workspaceCommandeer) *workspaceShowCommandeer {
+ commandeer := &workspaceShowCommandeer{
+ workspaceCommandeer: workspaceCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "show",
+ Short: "Show current workspace.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ show()
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
+
+func show() {
+
+ basicPath, _ := homedir.Dir()
+ inputFile, inputError := os.Open(basicPath + "/.ttctl/workspace.json")
+ if inputError != nil {
+ fmt.Printf("An error occurred on opening the inputfile")
+ return
+ }
+ defer inputFile.Close()
+
+ inputBytes, _ := ioutil.ReadAll(inputFile)
+
+ var wsConfig workspaceConfig
+
+ _ = json.Unmarshal(inputBytes, &wsConfig)
+
+ serializedConfig, _ := json.MarshalIndent(wsConfig, "", " ")
+ fmt.Print(string(serializedConfig))
+}
diff --git a/pkg/ttctl/workspaceSwitch.go b/pkg/ttctl/workspaceSwitch.go
new file mode 100644
index 00000000..21bcbfc3
--- /dev/null
+++ b/pkg/ttctl/workspaceSwitch.go
@@ -0,0 +1,31 @@
+package ttctl
+
+import (
+ "fmt"
+
+ cobra "github.com/spf13/cobra"
+)
+
+type workspaceSwitchCommandeer struct {
+ cmd *cobra.Command
+ workspaceCommandeer *workspaceCommandeer
+}
+
+func newWorkspaceSwitchCommandeer(workspaceCommandeer *workspaceCommandeer) *workspaceSwitchCommandeer {
+ commandeer := &workspaceSwitchCommandeer{
+ workspaceCommandeer: workspaceCommandeer,
+ }
+
+ cmd := &cobra.Command{
+ Use: "switch",
+ Short: "Switch to specific workspace.",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ fmt.Printf("here is a promptui integration,show current worksapce user id and wizard to fetch and switch to other sorkspace.")
+ return nil
+ },
+ }
+
+ commandeer.cmd = cmd
+
+ return commandeer
+}
diff --git a/pkg/ttserver/component/ApiHeader.go b/pkg/ttserver/component/ApiHeader.go
new file mode 100644
index 00000000..1116a807
--- /dev/null
+++ b/pkg/ttserver/component/ApiHeader.go
@@ -0,0 +1,16 @@
+package component
+
+type ApiEnv string
+
+const (
+ PRODUCTION ApiEnv = "PRODUCTION"
+ STAGING ApiEnv = "STAGING"
+ TEST ApiEnv = "TEST"
+ DAILY ApiEnv = "DAILY"
+)
+
+type ApiHeader struct {
+ Org string `json:"org" validate:"required" binding:"required"`
+ Project string `json:"project" validate:"required" binding:"required"`
+ Env string `json:"env" validate:"required,oneof='PRODUCTION' 'STAGING' 'TEST' 'DAILY'" binding:"required,oneof='PRODUCTION' 'STAGING' 'TEST' 'DAILY'"`
+}
diff --git a/pkg/ttserver/component/ApiResponse.go b/pkg/ttserver/component/ApiResponse.go
new file mode 100644
index 00000000..b7f53b18
--- /dev/null
+++ b/pkg/ttserver/component/ApiResponse.go
@@ -0,0 +1,6 @@
+package component
+
+type ApiResponse struct {
+ GmtCreate string `json:"gmt_create" validate:"required,datetime=2006-01-02 22:30:01"`
+ Endpoint string `json:"endpoint" validate:"required,url"`
+}
diff --git a/pkg/ttserver/path/ttweb.go b/pkg/ttserver/path/ttweb.go
new file mode 100644
index 00000000..fc68fd22
--- /dev/null
+++ b/pkg/ttserver/path/ttweb.go
@@ -0,0 +1,23 @@
+package path
+
+import (
+ "net/http"
+ "strings"
+
+ "github.com/Slahser/coup-de-grace/pkg/ttserver/component"
+ "github.com/gin-gonic/gin"
+)
+
+func TtWeb(context *gin.Context) {
+ var apiHeader component.ApiHeader
+
+ if err := context.BindHeader(&apiHeader); err != nil {
+ context.JSON(200, err)
+ }
+
+ funcName := context.Param("funcName")
+
+ fullPathStrings := []string{apiHeader.Org, apiHeader.Project, apiHeader.Env, funcName}
+
+ context.String(http.StatusOK, "your code in "+strings.Join(fullPathStrings, "-")+" is blabala")
+}
diff --git a/third_party/nuclio b/third_party/nuclio
new file mode 160000
index 00000000..dd336de9
--- /dev/null
+++ b/third_party/nuclio
@@ -0,0 +1 @@
+Subproject commit dd336de9db3e3bc22045da1e9afdc6422fc8dab3
diff --git a/vendor/README.md b/vendor/README.md
deleted file mode 100644
index 60e8be42..00000000
--- a/vendor/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# `/vendor`
-
-Application dependencies (managed manually or by your favorite dependency management tool like the new built-in, but still experimental, [`modules`](https://github.com/golang/go/wiki/Modules) feature).
-
-Don't commit your application dependencies if you are building a library.
-
-Note that since [`1.13`](https://golang.org/doc/go1.13#modules) Go also enabled the module proxy feature (using `https://proxy.golang.org` as their module proxy server by default). Read more about it [`here`](https://blog.golang.org/module-mirror-launch) to see if it fits all of your requirements and constraints. If it does, then you won't need the 'vendor' directory at all.