mirror of
https://github.com/gravitational/teleport
synced 2024-10-19 08:43:58 +00:00
rm -rf .cloudbuild (#20512)
This commit is contained in:
parent
e8e48a1c55
commit
6bcad73d69
|
@ -1,9 +0,0 @@
|
|||
steps:
|
||||
- name: public.ecr.aws/gravitational/docs:latest
|
||||
id: docs-test
|
||||
entrypoint: /bin/bash
|
||||
dir: /src
|
||||
args:
|
||||
- -c
|
||||
- ln -s /workspace /src/content && yarn markdown-lint
|
||||
timeout: 10m
|
|
@ -1,31 +0,0 @@
|
|||
timeout: 40m
|
||||
|
||||
options:
|
||||
machineType: E2_HIGHCPU_32
|
||||
|
||||
# This build needs to run in environments where the _GITHUB_DEPLOY_KEY_SRC
|
||||
# substitution is defined, but also environments where it isn't. The
|
||||
# ALLOW_LOOSE option disables GCB's strict checking of substitution usage,
|
||||
# so that the build will still run if _GITHUB_DEPLOY_KEY_SRC is not defined.
|
||||
substitution_option: ALLOW_LOOSE
|
||||
|
||||
steps:
|
||||
# Run the integration tests. Actual content of this job depends on the changes
|
||||
# detected in the PR
|
||||
- name: public.ecr.aws/gravitational/teleport-buildbox:teleport13
|
||||
id: run-tests
|
||||
dir: /workspace/.cloudbuild/scripts
|
||||
entrypoint: bash
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
go run ./cmd/integration-tests \
|
||||
-target "$_BASE_BRANCH" \
|
||||
-bucket test-logs \
|
||||
-build "$BUILD_ID" \
|
||||
-key-secret "$_GITHUB_DEPLOY_KEY_SRC" \
|
||||
-a "test-logs/*.json"
|
||||
# The actual makefile timeout is 30m. We add the 10 minute buffer here to
|
||||
# allow for setup and teardown time, reports to be saved, etc, if the
|
||||
# underlying tests time out.
|
||||
timeout: 40m
|
|
@ -1,6 +0,0 @@
|
|||
steps:
|
||||
- name: public.ecr.aws/gravitational/teleport-buildbox:teleport13
|
||||
id: lint
|
||||
args: ['make', 'lint']
|
||||
options:
|
||||
machineType: 'E2_HIGHCPU_32'
|
|
@ -1,23 +0,0 @@
|
|||
timeout: 25m
|
||||
|
||||
options:
|
||||
machineType: E2_HIGHCPU_32
|
||||
|
||||
steps:
|
||||
- name: public.ecr.aws/gravitational/teleport-buildbox-centos7:teleport13
|
||||
id: build-teleport
|
||||
dir: /workspace
|
||||
entrypoint: "/bin/bash"
|
||||
args:
|
||||
- '-c'
|
||||
- 'make build/tctl build/tsh build/tbot build/teleport'
|
||||
timeout: 10m
|
||||
env:
|
||||
- GOCACHE=/tmp/gocache
|
||||
|
||||
- name: gcr.io/cloud-builders/docker
|
||||
id: compatibility-test
|
||||
entrypoint: "/bin/bash"
|
||||
args:
|
||||
- './build.assets/build-test-compat.sh'
|
||||
timeout: 10m
|
|
@ -1,30 +0,0 @@
|
|||
timeout: 30m
|
||||
|
||||
options:
|
||||
machineType: E2_HIGHCPU_32
|
||||
|
||||
# This build needs to run in environments where the _GITHUB_DEPLOY_KEY_SRC
|
||||
# substitution is defined, but also environments where it isn't. The
|
||||
# ALLOW_LOOSE option disables GCB's strict checking of substitution usage,
|
||||
# so that the build will still run if _GITHUB_DEPLOY_KEY_SRC is not defined.
|
||||
substitution_option: ALLOW_LOOSE
|
||||
|
||||
steps:
|
||||
# Run the unit tests. Actual content of this job depends on the changes
|
||||
# detected in the PR
|
||||
- name: public.ecr.aws/gravitational/teleport-buildbox:teleport13
|
||||
id: run-tests
|
||||
dir: /workspace/.cloudbuild/scripts
|
||||
entrypoint: bash
|
||||
env:
|
||||
- 'HELM_PLUGINS=/home/ci/.local/share/helm/plugins-new'
|
||||
args:
|
||||
- -c
|
||||
- |
|
||||
go run ./cmd/unit-tests \
|
||||
-target "$_BASE_BRANCH" \
|
||||
-bucket test-logs \
|
||||
-build "$BUILD_ID" \
|
||||
-key-secret "$_GITHUB_DEPLOY_KEY_SRC" \
|
||||
-a "test-logs/*.json"
|
||||
timeout: 25m
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/artifacts"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/customflag"
|
||||
)
|
||||
|
||||
type commandlineArgs struct {
|
||||
workspace string
|
||||
targetBranch string
|
||||
commitSHA string
|
||||
skipChown bool
|
||||
buildID string
|
||||
artifactSearchPatterns customflag.StringArray
|
||||
bucket string
|
||||
githubKeySrc string
|
||||
skipUnshallow bool
|
||||
}
|
||||
|
||||
// validate ensures the suplied arguments are valid & internally consistent.
|
||||
func (args *commandlineArgs) validate() error {
|
||||
if args.workspace == "" {
|
||||
return trace.Errorf("workspace path must be set")
|
||||
}
|
||||
|
||||
var err error
|
||||
args.workspace, err = filepath.Abs(args.workspace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Unable to resole absolute path to workspace")
|
||||
}
|
||||
|
||||
if args.targetBranch == "" {
|
||||
return trace.Errorf("target branch must be set")
|
||||
}
|
||||
|
||||
if args.commitSHA == "" {
|
||||
return trace.Errorf("commit must be set")
|
||||
}
|
||||
|
||||
if len(args.artifactSearchPatterns) > 0 {
|
||||
if args.buildID == "" {
|
||||
return trace.Errorf("build ID required to upload artifacts")
|
||||
}
|
||||
|
||||
if args.bucket == "" {
|
||||
return trace.Errorf("storage bucket required to upload artifacts")
|
||||
}
|
||||
|
||||
args.artifactSearchPatterns, err = artifacts.ValidatePatterns(args.workspace, args.artifactSearchPatterns)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Bad artifact search path")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NOTE: changing the interface to this build script may require follow-up
|
||||
// changes in the cloudbuild yaml for both `teleport` and `teleport.e`
|
||||
func parseCommandLine() (*commandlineArgs, error) {
|
||||
args := &commandlineArgs{}
|
||||
|
||||
flag.StringVar(&args.workspace, "workspace", "/workspace", "Fully-qualified path to the build workspace")
|
||||
flag.StringVar(&args.targetBranch, "target", "", "The PR's target branch")
|
||||
flag.StringVar(&args.commitSHA, "commit", "HEAD", "The PR's latest commit SHA")
|
||||
flag.BoolVar(&args.skipChown, "skip-chown", false, "Skip reconfiguring the workspace for a nonroot user.")
|
||||
flag.StringVar(&args.buildID, "build", "", "The build ID")
|
||||
flag.StringVar(&args.bucket, "bucket", "", "The artifact storage bucket.")
|
||||
flag.Var(&args.artifactSearchPatterns, "a", "Path to artifacts. May be shell-globbed, and have multiple entries.")
|
||||
flag.StringVar(&args.githubKeySrc, "key-secret", "", "Location of github deploy token, as a Google Cloud Secret")
|
||||
flag.BoolVar(&args.skipUnshallow, "skip-unshallow", false, "Skip unshallowing the repository.")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
err := args.validate()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
|
@ -1,205 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/artifacts"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/changes"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/etcd"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/git"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/secrets"
|
||||
)
|
||||
|
||||
const (
|
||||
goCachesRootName = "gocache"
|
||||
nonrootUID = 1000
|
||||
nonrootGID = 1000
|
||||
)
|
||||
|
||||
// main is just a stub that prints out an error message and sets a nonzero exit
|
||||
// code on failure. All of the work happens in `innerMain()`.
|
||||
func main() {
|
||||
if err := innerMain(); err != nil {
|
||||
log.Fatalf("FAILED: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// innerMain parses the command line, performs the highlevel docs change check
|
||||
// and creates the marker file if necessary
|
||||
func innerMain() error {
|
||||
args, err := parseCommandLine()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
// If a github deploy key location was supplied...
|
||||
var deployKey []byte
|
||||
if args.githubKeySrc != "" {
|
||||
// fetch the deployment key from the GCB secret manager
|
||||
log.Infof("Fetching deploy key from %s", args.githubKeySrc)
|
||||
deployKey, err = secrets.Fetch(context.Background(), args.githubKeySrc)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed fetching deploy key")
|
||||
}
|
||||
}
|
||||
|
||||
if !args.skipUnshallow {
|
||||
unshallowCtx, unshallowCancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer unshallowCancel()
|
||||
err = git.UnshallowRepository(unshallowCtx, args.workspace, deployKey)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "unshallow failed")
|
||||
}
|
||||
}
|
||||
|
||||
goCacheRoot := filepath.Join(os.TempDir(), goCachesRootName)
|
||||
env := map[string]string{
|
||||
"GOCACHE": filepath.Join(goCacheRoot, "go-build"),
|
||||
"GOMODCACHE": filepath.Join(goCacheRoot, "pkg"),
|
||||
}
|
||||
|
||||
log.Println("Analyzing code changes")
|
||||
ch, err := changes.Analyze(args.workspace, args.targetBranch, args.commitSHA)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Failed analyzing code")
|
||||
}
|
||||
|
||||
if !ch.Code {
|
||||
log.Println("No code changes detected. Skipping tests.")
|
||||
return nil
|
||||
}
|
||||
|
||||
// From this point on, whatever happens we want to upload any artifacts
|
||||
// produced by the build
|
||||
defer func() {
|
||||
prefix := fmt.Sprintf("%s/artifacts", args.buildID)
|
||||
timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
artifacts.FindAndUpload(timeoutCtx, args.bucket, prefix, args.artifactSearchPatterns)
|
||||
}()
|
||||
|
||||
log.Printf("Running root-only integration tests...")
|
||||
err = runRootIntegrationTests(args.workspace, env)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Root-only integration tests failed")
|
||||
}
|
||||
log.Println("Root-only integration tests passed.")
|
||||
|
||||
if !args.skipChown {
|
||||
// We run some build steps as root and others as a non user, and we
|
||||
// want the nonroot user to be able to manipulate the artifacts
|
||||
// created by root, so we `chown -R` the whole workspace & module
|
||||
// cache to allow it.
|
||||
|
||||
log.Printf("Reconfiguring workspace for nonroot user")
|
||||
err = chownR(args.workspace, nonrootUID, nonrootGID)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed reconfiguring workspace")
|
||||
}
|
||||
|
||||
log.Printf("Reconfiguring module cache for nonroot user")
|
||||
err = chownR(goCacheRoot, nonrootUID, nonrootGID)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed reconfiguring module cache")
|
||||
}
|
||||
}
|
||||
|
||||
// Note that we run `etcd` as nonroot here. The files created by etcd live
|
||||
// inside the directory searched by `go list ./...` when generating the list
|
||||
// of packages to test, and so making them owned by root produces a heap of
|
||||
// diagnostic warnings that would pollute the build log and just confuse
|
||||
// people when they are trying to work out why their build failed.
|
||||
log.Printf("Starting etcd...")
|
||||
timeoutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
etcdSvc, err := etcd.Start(timeoutCtx, args.workspace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed starting etcd")
|
||||
}
|
||||
defer etcdSvc.Stop()
|
||||
|
||||
log.Printf("Running nonroot integration tests...")
|
||||
err = runNonrootIntegrationTests(args.workspace, nonrootUID, nonrootGID, env)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Nonroot integration tests failed")
|
||||
}
|
||||
|
||||
log.Printf("Non-root integration tests passed.")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runRootIntegrationTests(workspace string, env map[string]string) error {
|
||||
// Run root integration tests
|
||||
cmd := exec.Command("make", "rdpclient", "integration-root")
|
||||
cmd.Dir = workspace
|
||||
cmd.Env = os.Environ()
|
||||
for k, v := range env {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k, v))
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func runNonrootIntegrationTests(workspace string, uid, gid int, env map[string]string) error {
|
||||
cmd := exec.Command("make", "integration")
|
||||
cmd.Dir = workspace
|
||||
cmd.Env = append(os.Environ(), "TELEPORT_ETCD_TEST=yes")
|
||||
for k, v := range env {
|
||||
cmd.Env = append(cmd.Env, fmt.Sprintf("%v=%v", k, v))
|
||||
}
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
// make the command run under the supplied nonroot account
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Credential: &syscall.Credential{
|
||||
Uid: uint32(uid),
|
||||
Gid: uint32(gid),
|
||||
},
|
||||
}
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// chownR changes the owner of each file in the workspace to the supplied
|
||||
// uid:guid combo.
|
||||
func chownR(workspace string, uid, gid int) error {
|
||||
err := filepath.WalkDir(workspace, func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.Chown(path, uid, gid)
|
||||
})
|
||||
|
||||
return trace.Wrap(err, "Failed changing file owner")
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
//go:build linux
|
||||
|
||||
/*
|
||||
Copyright 2021 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/artifacts"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/changes"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/customflag"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/etcd"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/git"
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/secrets"
|
||||
)
|
||||
|
||||
// debugFsPath is the path where debugfs should be mounted.
|
||||
const debugFsPath = "/sys/kernel/debug"
|
||||
|
||||
// main is just a stub that prints out an error message and sets a nonzero exit
|
||||
// code on failure. All the work happens in `innerMain()`.
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatalf("FAILED: %s", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type commandlineArgs struct {
|
||||
workspace string
|
||||
targetBranch string
|
||||
commitSHA string
|
||||
buildID string
|
||||
artifactSearchPatterns customflag.StringArray
|
||||
bucket string
|
||||
githubKeySrc string
|
||||
skipUnshallow bool
|
||||
}
|
||||
|
||||
// NOTE: changing the interface to this build script may require follow-up
|
||||
// changes in the cloudbuild yaml for both `teleport` and `teleport.e`
|
||||
func parseCommandLine() (commandlineArgs, error) {
|
||||
args := commandlineArgs{}
|
||||
|
||||
flag.StringVar(&args.workspace, "workspace", "/workspace", "Fully-qualified path to the build workspace")
|
||||
flag.StringVar(&args.targetBranch, "target", "", "The PR's target branch")
|
||||
flag.StringVar(&args.commitSHA, "commit", "HEAD", "The PR's latest commit SHA")
|
||||
flag.StringVar(&args.buildID, "build", "", "The build ID")
|
||||
flag.StringVar(&args.bucket, "bucket", "", "The artifact storage bucket.")
|
||||
flag.Var(&args.artifactSearchPatterns, "a", "Path to artifacts. May be globbed, and have multiple entries.")
|
||||
flag.StringVar(&args.githubKeySrc, "key-secret", "", "Location of github deploy token, as a Google Cloud Secret")
|
||||
flag.BoolVar(&args.skipUnshallow, "skip-unshallow", false, "Skip unshallowing the repository.")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if args.workspace == "" {
|
||||
return args, trace.Errorf("workspace path must be set")
|
||||
}
|
||||
|
||||
var err error
|
||||
args.workspace, err = filepath.Abs(args.workspace)
|
||||
if err != nil {
|
||||
return args, trace.Wrap(err, "Unable to resolve absolute path to workspace")
|
||||
}
|
||||
|
||||
if args.targetBranch == "" {
|
||||
return args, trace.Errorf("target branch must be set")
|
||||
}
|
||||
|
||||
if args.commitSHA == "" {
|
||||
return args, trace.Errorf("commit must be set")
|
||||
}
|
||||
|
||||
if len(args.artifactSearchPatterns) > 0 {
|
||||
if args.buildID == "" {
|
||||
return args, trace.Errorf("build ID required to upload artifacts")
|
||||
}
|
||||
|
||||
if args.bucket == "" {
|
||||
return args, trace.Errorf("storage bucket required to upload artifacts")
|
||||
}
|
||||
|
||||
args.artifactSearchPatterns, err = artifacts.ValidatePatterns(args.workspace, args.artifactSearchPatterns)
|
||||
if err != nil {
|
||||
return args, trace.Wrap(err, "Bad artifact search path")
|
||||
}
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
// run parses the command line, performs the high level docs change check
|
||||
// and creates the marker file if necessary
|
||||
func run() error {
|
||||
args, err := parseCommandLine()
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
// If a github deploy key location was supplied...
|
||||
var deployKey []byte
|
||||
if args.githubKeySrc != "" {
|
||||
// fetch the deployment key from the GCB secret manager
|
||||
log.Infof("Fetching deploy key from %s", args.githubKeySrc)
|
||||
deployKey, err = secrets.Fetch(context.Background(), args.githubKeySrc)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed fetching deploy key")
|
||||
}
|
||||
}
|
||||
|
||||
if !args.skipUnshallow {
|
||||
unshallowCtx, unshallowCancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer unshallowCancel()
|
||||
err = git.UnshallowRepository(unshallowCtx, args.workspace, deployKey)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "unshallow failed")
|
||||
}
|
||||
}
|
||||
|
||||
log.Println("Analyzing code changes")
|
||||
ch, err := changes.Analyze(args.workspace, args.targetBranch, args.commitSHA)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Failed analyzing code")
|
||||
}
|
||||
log.Printf("Detected changes: %+v", ch)
|
||||
|
||||
if !ch.HasCodeChanges() {
|
||||
log.Println("No code changes detected. Skipping tests.")
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Starting etcd...")
|
||||
timeoutCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
etcdSvc, err := etcd.Start(timeoutCtx, args.workspace)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed starting etcd")
|
||||
}
|
||||
defer etcdSvc.Stop()
|
||||
|
||||
// From this point on, whatever happens we want to upload any artifacts
|
||||
// produced by the build
|
||||
defer func() {
|
||||
prefix := fmt.Sprintf("%s/artifacts", args.buildID)
|
||||
timeoutCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
artifacts.FindAndUpload(timeoutCtx, args.bucket, prefix, args.artifactSearchPatterns)
|
||||
}()
|
||||
|
||||
log.Printf("Mounting debugfs")
|
||||
if err := mountDebugFS(); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
log.Printf("Running unit tests...")
|
||||
err = runUnitTests(args.workspace, ch)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "unit tests failed")
|
||||
}
|
||||
|
||||
log.Printf("PASS")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runUnitTests(workspace string, ch changes.Changes) error {
|
||||
enableTests := []string{
|
||||
"TELEPORT_ETCD_TEST=yes",
|
||||
"TELEPORT_XAUTH_TEST=yes",
|
||||
"TELEPORT_BPF_TEST=yes",
|
||||
}
|
||||
|
||||
var targets []string
|
||||
if ch.Code {
|
||||
targets = append(targets, "test-go", "test-sh", "test-api")
|
||||
}
|
||||
if ch.Helm {
|
||||
targets = append(targets, "test-helm")
|
||||
}
|
||||
if ch.CI {
|
||||
targets = append(targets, "test-ci")
|
||||
}
|
||||
if ch.Rust {
|
||||
targets = append(targets, "test-rust")
|
||||
}
|
||||
if ch.Operator {
|
||||
targets = append(targets, "test-operator")
|
||||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
log.Printf("No tests to run: %+v", ch)
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Printf("Running test targets: %v", strings.Join(targets, " "))
|
||||
cmd := exec.Command("make", targets...)
|
||||
cmd.Dir = workspace
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, enableTests...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
// mountDebugFS mounts debugfs at /sys/kernel/debug, so BPF test can run in GCB.
|
||||
func mountDebugFS() error {
|
||||
if isDebugFsMounted() {
|
||||
return nil
|
||||
}
|
||||
// equivalent to: mount -t debugfs none /sys/kernel/debug/
|
||||
if err := unix.Mount("debugfs", debugFsPath, "debugfs", 0, ""); err != nil {
|
||||
return trace.Wrap(err, "failed to mount debugfs")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isDebugFsMounted returns true if debugfs is mounted, false otherwise.
|
||||
func isDebugFsMounted() bool {
|
||||
mounts, err := os.ReadFile("/proc/mounts")
|
||||
if err != nil {
|
||||
log.Warningf("Failed to read /proc/mounts: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(mounts), "\n") {
|
||||
tokens := strings.Fields(line)
|
||||
if len(tokens) == 6 && tokens[0] == "debugfs" && tokens[1] == debugFsPath {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
module github.com/gravitational/teleport/.cloudbuild/scripts
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
cloud.google.com/go/secretmanager v1.2.0
|
||||
cloud.google.com/go/storage v1.19.0
|
||||
github.com/go-git/go-git/v5 v5.4.2
|
||||
github.com/gravitational/trace v1.1.15
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.100.2 // indirect
|
||||
cloud.google.com/go/compute v0.1.0 // indirect
|
||||
cloud.google.com/go/iam v0.1.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.16 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/emirpasic/gods v1.12.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.3.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/go-cmp v0.5.7 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jonboulle/clockwork v0.2.2 // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/api v0.67.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/grpc v1.44.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
)
|
|
@ -1,686 +0,0 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
|
||||
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
|
||||
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
|
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=
|
||||
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
|
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v0.1.0 h1:rSUBvAyVwNJ5uQCKNJFMwPtTvJkfN38b6Pvb9zZoqJ8=
|
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
|
||||
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/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=
|
||||
cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68=
|
||||
cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/secretmanager v1.2.0 h1:VR6MzO4wjTj5jQKTPpsZhCF2PqqdAAZmN54BwJbQPhs=
|
||||
cloud.google.com/go/secretmanager v1.2.0/go.mod h1:HNMYTaLrMrAN37vi2mM2vvFgjgaoCE1qvtccCIJwFRc=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.19.0 h1:XOQSnPJD8hRtZJ3VdCyK0mBZsGGImrzPAMbSWcHSe6Q=
|
||||
cloud.google.com/go/storage v1.19.0/go.mod h1:6rgiTRjOqI/Zd9YKimub5TIB4d+p3LH33V3ZE1DMuUM=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||
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/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
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/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ=
|
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
|
||||
github.com/gravitational/trace v1.1.15 h1:dfaFcARt110nCX6RSvrcRUbvRawEYAasXyCqnhXo0Xg=
|
||||
github.com/gravitational/trace v1.1.15/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
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-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ=
|
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
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/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
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/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
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 v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
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/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-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-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-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420 h1:a8jGStKg0XqKDlKqjLrXn0ioF5MH36pT7Z0BRTqLhbk=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
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/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/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/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-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-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-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
|
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
|
||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
|
||||
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
|
||||
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
|
||||
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||
google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM=
|
||||
google.golang.org/api v0.65.0/go.mod h1:ArYhxgGadlWmqO1IqVujw6Cs8IdD33bTmzKo2Sh+cbg=
|
||||
google.golang.org/api v0.67.0 h1:lYaaLa+x3VVUhtosaK9xihwQ9H9KRa557REHwwZ2orM=
|
||||
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
|
||||
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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
|
||||
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
|
||||
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c h1:TU4rFa5APdKTq0s6B7WTsH6Xmx0Knj86s6Biz56mErE=
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
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=
|
|
@ -1,193 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package artifacts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ValidatePatterns checks that the supplied patterns are rooted inside
|
||||
// the given workspace. Workspace is expected to be the fully-qualified
|
||||
// path to the workspace root. Returns a collection of patterns that
|
||||
// have been validated and canonicalised.
|
||||
func ValidatePatterns(workspace string, patterns []string) ([]string, error) {
|
||||
result := make([]string, len(patterns))
|
||||
for i, p := range patterns {
|
||||
if path.IsAbs(p) {
|
||||
return nil, trace.BadParameter("Cannot use absolute path to artifact: %s", p)
|
||||
}
|
||||
|
||||
fullyQualifiedPattern, err := filepath.Abs(filepath.Join(workspace, p))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(fullyQualifiedPattern, workspace) {
|
||||
return nil, trace.BadParameter("artifact patten points outside of workspace: %s", p)
|
||||
}
|
||||
|
||||
result[i] = fullyQualifiedPattern
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindAndUpload finds all of the files referenced by the supplied patterns
|
||||
// and uploads them to the supplied GCS bucket. The supplied patterns are
|
||||
// expected to be fully-qualified paths, and will be searched without changing
|
||||
// the current directory.
|
||||
//
|
||||
// Artifacts from various paths will be aggregated into one place in the
|
||||
// bucket with the supplied prefix, using the file's base name to disambiguate,
|
||||
// so be wary of including multiple artifacts with the same name.
|
||||
//
|
||||
// For example, given a directory tree that looks like
|
||||
//
|
||||
// /
|
||||
// ├── mystery-machine.yaml
|
||||
// ├── dogs
|
||||
// │ └── scooby.yaml
|
||||
// └── people
|
||||
// └── shaggy.yaml
|
||||
//
|
||||
// calling
|
||||
//
|
||||
// Upload(ctx, "bucket-name", "build-unique-id", []string{"/**/*.yaml"}))
|
||||
//
|
||||
// will result in a bucket with the added objects
|
||||
//
|
||||
// - "build-unique-id/mystery-machine.yaml"
|
||||
// - "build-unique-id/scooby.yaml"
|
||||
// - "build-unique-id/shaggy.yaml"
|
||||
func FindAndUpload(ctx context.Context, bucketName, objectPrefix string, artifactPatterns []string) error {
|
||||
artifacts := find(artifactPatterns)
|
||||
|
||||
if len(artifacts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
client, err := storage.NewClient(ctx)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
bucketHandle := bucketAdaptor{client.Bucket(bucketName)}
|
||||
|
||||
return upload(ctx, bucketHandle, objectPrefix, artifacts)
|
||||
}
|
||||
|
||||
// bucket presents a minimal interface to a storage bucket, allowing us to
|
||||
// mock out GCB for testing
|
||||
type objectHandle interface {
|
||||
NewWriter(context.Context) io.WriteCloser
|
||||
}
|
||||
|
||||
// bucket presents an interface to a storage bucket, allowing us to
|
||||
// mock out GCB for testing
|
||||
type bucketHandle interface {
|
||||
Object(name string) objectHandle
|
||||
}
|
||||
|
||||
// find searches through the supplied glob patterns and collects the matching
|
||||
// file paths.
|
||||
func find(artifactPatterns []string) []string {
|
||||
log.Printf("Scanning for artifacts...")
|
||||
artifacts := []string{}
|
||||
for _, pattern := range artifactPatterns {
|
||||
matches, err := filepath.Glob(pattern)
|
||||
if err != nil {
|
||||
log.Printf("Failed scanning for artifacts matching %q: %s", pattern, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
for _, match := range matches {
|
||||
info, err := os.Stat(match)
|
||||
if err != nil {
|
||||
log.Warnf("Failed stating %q: %s", pattern, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if info.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
artifacts = append(artifacts, match)
|
||||
}
|
||||
}
|
||||
return artifacts
|
||||
}
|
||||
|
||||
// upload uploads a set of files to the indicated artifact bucket with the
|
||||
// supplied prefix.
|
||||
//
|
||||
// Note that artifacts from various paths will be aggregated into one place in
|
||||
// the bucket under the supplied prefix, using the file's base name to
|
||||
// disambiguate. Be wary of including multiple artifacts with the same name, as
|
||||
// later object may clobber earlier ones.
|
||||
func upload(ctx context.Context, bucket bucketHandle, prefix string, files []string) error {
|
||||
var uploadErrors *multierror.Error
|
||||
|
||||
for _, filename := range files {
|
||||
objectName := path.Join(prefix, path.Base(filename))
|
||||
log.Infof("Uploading artifact %q as %q", filename, objectName)
|
||||
|
||||
if err := uploadFile(ctx, bucket, objectName, filename); err != nil {
|
||||
log.WithError(err).Warnf("Artifact upload failed for %q", filename)
|
||||
uploadErrors = multierror.Append(uploadErrors, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return uploadErrors.ErrorOrNil()
|
||||
}
|
||||
|
||||
// uploadFile uploads an individual file to the supplied storage bucket.
|
||||
func uploadFile(ctx context.Context, bucket bucketHandle, objectName, filename string) error {
|
||||
obj := bucket.Object(objectName)
|
||||
|
||||
source, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "Failed opening file to upload")
|
||||
}
|
||||
defer source.Close()
|
||||
|
||||
sink := obj.NewWriter(ctx)
|
||||
_, err = io.Copy(sink, source)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
// Note that in most cases, any upload errors won't be reported
|
||||
// until the writer is closed, so we can't just do a simple
|
||||
// `defer close()`
|
||||
if err = sink.Close(); err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
return trace.Wrap(err)
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package artifacts
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func write(t *testing.T, data []byte, path ...string) string {
|
||||
t.Helper()
|
||||
filePath := filepath.Join(path...)
|
||||
require.NoError(t, os.MkdirAll(filepath.Dir(filePath), 0777))
|
||||
require.NoError(t, os.WriteFile(filePath, data, 0644))
|
||||
return filePath
|
||||
}
|
||||
|
||||
func touch(t *testing.T, path ...string) string {
|
||||
t.Helper()
|
||||
return write(t, []byte{}, path...)
|
||||
}
|
||||
|
||||
func TestValidatePatterns(t *testing.T) {
|
||||
workspace := t.TempDir()
|
||||
|
||||
t.Run("Patterns are expanded", func(t *testing.T) {
|
||||
patterns := []string{"alpha", "nested/beta", "*"}
|
||||
|
||||
expected := []string{
|
||||
filepath.Join(workspace, "alpha"),
|
||||
filepath.Join(workspace, "nested", "beta"),
|
||||
filepath.Join(workspace, "*"),
|
||||
}
|
||||
|
||||
actual, err := ValidatePatterns(workspace, patterns)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, actual, expected)
|
||||
})
|
||||
|
||||
t.Run("Paths are canonicalised", func(t *testing.T) {
|
||||
patterns := []string{
|
||||
"nested/../alpha",
|
||||
"./beta",
|
||||
}
|
||||
|
||||
expected := []string{
|
||||
filepath.Join(workspace, "alpha"),
|
||||
filepath.Join(workspace, "beta"),
|
||||
}
|
||||
|
||||
actual, err := ValidatePatterns(workspace, patterns)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, actual, expected)
|
||||
})
|
||||
|
||||
t.Run("Paths outside workspace fail", func(t *testing.T) {
|
||||
t.Run("fully-qualified path", func(t *testing.T) {
|
||||
_, err := ValidatePatterns(workspace, []string{t.TempDir()})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("relative path", func(t *testing.T) {
|
||||
target := "../../root/**/*"
|
||||
_, err := ValidatePatterns(workspace, []string{target})
|
||||
require.Error(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestFindArtifacts(t *testing.T) {
|
||||
workspace := t.TempDir()
|
||||
|
||||
alpha := touch(t, workspace, "alpha.yaml")
|
||||
beta := touch(t, workspace, "beta.yaml")
|
||||
gamma := touch(t, workspace, "gamma.some-other-extension")
|
||||
delta := touch(t, workspace, "nested", "delta.yaml")
|
||||
epsilon := touch(t, workspace, "nested", "epsilon.yaml")
|
||||
zeta := touch(t, workspace, "nested", "deeply", "zeta")
|
||||
eta := touch(t, workspace, "nested", "very", "deeply", "eta.yaml")
|
||||
|
||||
t.Run("root-dir", func(t *testing.T) {
|
||||
patterns := []string{filepath.Join(workspace, "*")}
|
||||
actual := find(patterns)
|
||||
expected := []string{alpha, beta, gamma}
|
||||
require.ElementsMatch(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("prefix", func(t *testing.T) {
|
||||
patterns := []string{
|
||||
filepath.Join(workspace, "nested/*"),
|
||||
filepath.Join(workspace, "nested/*/*"),
|
||||
filepath.Join(workspace, "nested/*/*/*"),
|
||||
}
|
||||
actual := find(patterns)
|
||||
expected := []string{delta, epsilon, zeta, eta}
|
||||
require.ElementsMatch(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("suffix", func(t *testing.T) {
|
||||
patterns := []string{
|
||||
filepath.Join(workspace, "*.yaml"),
|
||||
filepath.Join(workspace, "*/*.yaml"),
|
||||
filepath.Join(workspace, "*/*/*.yaml"),
|
||||
filepath.Join(workspace, "*/*/*/*.yaml"),
|
||||
}
|
||||
actual := find(patterns)
|
||||
expected := []string{alpha, beta, delta, epsilon, eta}
|
||||
require.ElementsMatch(t, expected, actual)
|
||||
})
|
||||
|
||||
t.Run("infix", func(t *testing.T) {
|
||||
patterns := []string{filepath.Join(workspace, "*/very/deeply/*")}
|
||||
actual := find(patterns)
|
||||
expected := []string{eta}
|
||||
require.ElementsMatch(t, expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpload(t *testing.T) {
|
||||
workspace := t.TempDir()
|
||||
|
||||
ctx := context.Background()
|
||||
bucket := new(mockBucket)
|
||||
|
||||
mockArtifact := func(content []byte, path ...string) (string, *bytes.Buffer) {
|
||||
// Create the source file that the upload() function should find
|
||||
// and upload
|
||||
src := write(t, content, path...)
|
||||
|
||||
// Rig up a mock that will receive the "uploaded" content
|
||||
dst := &bytes.Buffer{}
|
||||
obj := &mockStorageObject{}
|
||||
obj.On("NewWriter", mock.Anything).
|
||||
Return(&closeWrapper{Writer: dst}).
|
||||
Once()
|
||||
|
||||
bucket.On("Object", "artifacts/"+path[len(path)-1]).
|
||||
Return(obj).
|
||||
Once()
|
||||
return src, dst
|
||||
}
|
||||
|
||||
// Given a configured artifact list and a mocked-out upload receiver...
|
||||
const alphaContent = "I am the very model of a modern major-general"
|
||||
alphaSrc, alphaDst := mockArtifact([]byte(alphaContent), workspace, "nested", "alpha.txt")
|
||||
|
||||
const betaContent = "I've information vegetable, animal, and mineral"
|
||||
betaSrc, betaDst := mockArtifact([]byte(betaContent), workspace, "beta.txt")
|
||||
|
||||
// When I upload artifact files...
|
||||
files := []string{alphaSrc, betaSrc}
|
||||
err := upload(ctx, bucket, "artifacts", files)
|
||||
|
||||
// Expect that the upload succeeds
|
||||
require.NoError(t, err)
|
||||
|
||||
// And that the file content was written to the objects
|
||||
require.Equal(t, alphaContent, alphaDst.String())
|
||||
require.Equal(t, betaContent, betaDst.String())
|
||||
}
|
||||
|
||||
func TestFailedUpload(t *testing.T) {
|
||||
workspace := t.TempDir()
|
||||
|
||||
ctx := context.Background()
|
||||
bucket := new(mockBucket)
|
||||
|
||||
mockArtifact := func(content []byte, dst io.WriteCloser, path ...string) string {
|
||||
// Create the source item that the upload() function should find
|
||||
// and upload
|
||||
src := write(t, content, path...)
|
||||
|
||||
// Rig up a mock that will receive the "uploaded" content
|
||||
obj := &mockStorageObject{}
|
||||
obj.On("NewWriter", mock.Anything).
|
||||
Return(dst).
|
||||
Once()
|
||||
|
||||
bucket.On("Object", "artifacts/"+path[len(path)-1]).
|
||||
Return(obj).
|
||||
Once()
|
||||
return src
|
||||
}
|
||||
|
||||
mockHappyPath := func(content []byte, path ...string) (string, *bytes.Buffer) {
|
||||
// Mock up an uploader that will just succeed
|
||||
dst := &bytes.Buffer{}
|
||||
src := mockArtifact(content, &closeWrapper{Writer: dst}, path...)
|
||||
return src, dst
|
||||
}
|
||||
|
||||
// Given a configured artifact list and a mocked-out upload receiver...
|
||||
const alphaContent = "I am the very model of a modern major-general"
|
||||
alphaSrc, alphaDst := mockHappyPath([]byte(alphaContent), workspace, "nested", "alpha.txt")
|
||||
|
||||
// .. where one of the uploads will fail on write...
|
||||
const betaContent = "I've information vegetable, animal, and mineral"
|
||||
betaErr := errors.New("Spontaneous failure")
|
||||
betaDst := &mockWriter{}
|
||||
betaDst.
|
||||
On("Write", mock.AnythingOfType("[]uint8")).
|
||||
Return(0, betaErr)
|
||||
betaSrc := mockArtifact([]byte(betaContent), betaDst, workspace, "fail-on-write.txt")
|
||||
|
||||
// .. and another will fail on close...
|
||||
const gammaContent = "I know the kings of England, and I quote the fights Historical"
|
||||
gammaErr := errors.New("Fail on close")
|
||||
gammaDst := &mockWriter{}
|
||||
gammaDst.On("Write", mock.AnythingOfType("[]uint8"))
|
||||
gammaDst.On("Close").Return(gammaErr)
|
||||
gammaSrc := mockArtifact([]byte(gammaContent), gammaDst, workspace, "fail-on-close.txt")
|
||||
|
||||
// .. and another flat-out-fails to exist...
|
||||
const deltaContent = "From Marathon to Waterloo, in order categorical"
|
||||
deltaSrc := mockArtifact([]byte(deltaContent), &mockWriter{}, workspace, "no", "such", "file.txt")
|
||||
require.NoError(t, os.Remove(deltaSrc))
|
||||
|
||||
// with a final entry that should succeed
|
||||
const epsilonContent = "I'm very well acquainted, too, with matters Mathematical"
|
||||
epsilonSrc, epsilonDst := mockHappyPath([]byte(epsilonContent), workspace, "epsilon.txt")
|
||||
|
||||
// When I actually try to upload these files...
|
||||
files := []string{alphaSrc, betaSrc, gammaSrc, deltaSrc, epsilonSrc}
|
||||
err := upload(ctx, bucket, "artifacts", files)
|
||||
|
||||
// Expect that 3 out of the 5 uploads failed (implying an overall failure)
|
||||
require.Error(t, err)
|
||||
errs := err.(*multierror.Error)
|
||||
require.Equal(t, 3, errs.Len())
|
||||
|
||||
// ...but that the rest are still uploaded
|
||||
require.Equal(t, alphaContent, alphaDst.String())
|
||||
require.Equal(t, epsilonContent, epsilonDst.String())
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package artifacts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
type mockBucket struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (b *mockBucket) Object(name string) objectHandle {
|
||||
args := b.Called(name)
|
||||
return args.Get(0).(objectHandle)
|
||||
}
|
||||
|
||||
type mockStorageObject struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (obj *mockStorageObject) NewWriter(ctx context.Context) io.WriteCloser {
|
||||
args := obj.Called(ctx)
|
||||
return args.Get(0).(io.WriteCloser)
|
||||
}
|
||||
|
||||
type closeWrapper struct {
|
||||
io.Writer
|
||||
closeError error
|
||||
}
|
||||
|
||||
func (w *closeWrapper) Close() error {
|
||||
return w.closeError
|
||||
}
|
||||
|
||||
type mockWriter struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (w *mockWriter) Write(data []byte) (int, error) {
|
||||
args := w.Called(data)
|
||||
|
||||
// If no explicit return value was set in the mock then return as if we
|
||||
// have written the whole buffer. The testify mock library makes it hard
|
||||
// to return values calculated at execution time (as opposed to at test
|
||||
// construction), so we add this shim to make writing tests with it a
|
||||
// bit easier.
|
||||
if len(args) == 0 {
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
return args.Int(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (w *mockWriter) Close() error {
|
||||
args := w.Called()
|
||||
return args.Error(0)
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package artifacts
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
)
|
||||
|
||||
// objectAdaptor wraps a live GCB storage handle in our minimal storage
|
||||
// interface
|
||||
type objectAdaptor struct{ *storage.ObjectHandle }
|
||||
|
||||
func (adaptor objectAdaptor) NewWriter(ctx context.Context) io.WriteCloser {
|
||||
return adaptor.ObjectHandle.NewWriter(ctx)
|
||||
}
|
||||
|
||||
// objectAdaptor wraps a live GCB storage handle in our minimal bucket
|
||||
// interface
|
||||
type bucketAdaptor struct{ *storage.BucketHandle }
|
||||
|
||||
func (adaptor bucketAdaptor) Object(name string) objectHandle {
|
||||
return objectAdaptor{adaptor.BucketHandle.Object(name)}
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Package changes implements a script to analyze the changes between
|
||||
// a commit and a given branch. It is designed for use when comparing
|
||||
// the tip of a PR against the merge target
|
||||
package changes
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/go-git/go-git/v5/plumbing/object"
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Changes describes the kind of changes found in the analyzed workspace.
|
||||
type Changes struct {
|
||||
CI bool
|
||||
Docs bool
|
||||
Code bool
|
||||
Enterprise bool
|
||||
Helm bool
|
||||
Operator bool
|
||||
Rust bool
|
||||
}
|
||||
|
||||
// HasCodeChanges returns true if the changeset includes code changes.
|
||||
func (c Changes) HasCodeChanges() bool {
|
||||
return c.Code || c.Helm || c.CI || c.Rust || c.Operator
|
||||
}
|
||||
|
||||
// Analyze examines the workspace for specific changes using its git history,
|
||||
// and then collates and returns a report.
|
||||
func Analyze(workspaceDir string, targetBranch string, commitSHA string) (Changes, error) {
|
||||
log.Printf("Opening workspace %q as git repo\n", workspaceDir)
|
||||
repo, err := git.PlainOpen(workspaceDir)
|
||||
if err != nil {
|
||||
return Changes{}, trace.Wrap(err, "failed opening workspace as a repo")
|
||||
}
|
||||
|
||||
changes, err := getChanges(repo, targetBranch, commitSHA)
|
||||
if err != nil {
|
||||
return Changes{}, trace.Wrap(err, "failed extracting changes")
|
||||
}
|
||||
|
||||
report := Changes{}
|
||||
|
||||
for _, change := range changes {
|
||||
path := getChangePath(change)
|
||||
switch {
|
||||
case path == "":
|
||||
continue
|
||||
|
||||
case path == "e":
|
||||
report.Enterprise = true
|
||||
|
||||
case isDocChange(path):
|
||||
report.Docs = true
|
||||
|
||||
case isHelmChange(path):
|
||||
report.Helm = true
|
||||
|
||||
case isRustChange(path):
|
||||
report.Rust = true
|
||||
|
||||
case isCIChange(path):
|
||||
report.CI = true
|
||||
|
||||
case isOperatorChange(path):
|
||||
report.Operator = true
|
||||
|
||||
default:
|
||||
report.Code = true
|
||||
}
|
||||
|
||||
if report.Docs && report.Code && report.Enterprise {
|
||||
// There's no sense in exhaustively listing all the changes if
|
||||
// the answer won't change, so bail early.
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func isCIChange(path string) bool {
|
||||
path = strings.ToLower(path)
|
||||
return strings.HasPrefix(path, ".cloudbuild/scripts")
|
||||
}
|
||||
|
||||
func isOperatorChange(path string) bool {
|
||||
path = strings.ToLower(path)
|
||||
// dependency updates can impact CRD generation,
|
||||
// so ensure that operator tests are run when
|
||||
// dependencies change
|
||||
return path == "go.mod" ||
|
||||
path == "go.sum" ||
|
||||
strings.HasPrefix(path, "operator/") ||
|
||||
strings.HasPrefix(path, "api/types") || // the operator uses directly Teleport types
|
||||
strings.HasPrefix(path, "lib/tbot") // the operator embeds a tbot instance
|
||||
}
|
||||
|
||||
func isDocChange(path string) bool {
|
||||
path = strings.ToLower(path)
|
||||
return strings.HasPrefix(path, "docs/") ||
|
||||
strings.HasSuffix(path, ".mdx") ||
|
||||
strings.HasSuffix(path, ".md") ||
|
||||
strings.HasPrefix(path, "rfd/")
|
||||
}
|
||||
|
||||
func isRustChange(path string) bool {
|
||||
path = strings.ToLower(path)
|
||||
return strings.HasSuffix(path, ".rs") ||
|
||||
strings.HasSuffix(path, "Cargo.toml") ||
|
||||
strings.HasSuffix(path, "Cargo.lock")
|
||||
}
|
||||
|
||||
func isHelmChange(path string) bool {
|
||||
path = strings.ToLower(path)
|
||||
return strings.HasPrefix(path, "examples/chart/")
|
||||
}
|
||||
|
||||
// getChanges resolves the head of target branch and compares the trees at the
|
||||
// the target branch and the supplied commit SHA.
|
||||
func getChanges(repo *git.Repository, targetBranch, commit string) (object.Changes, error) {
|
||||
log.Printf("Getting worktree for target branch %s", targetBranch)
|
||||
targetTree, err := getBranchTree(repo, targetBranch)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed getting target branch worktree")
|
||||
}
|
||||
|
||||
log.Printf("Getting filetree for commit %s", commit)
|
||||
commitTree, err := getCommitTree(repo, commit)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed getting target branch worktree")
|
||||
}
|
||||
|
||||
log.Printf("Comparing commit %q with target branch %q", commit, targetBranch)
|
||||
changes, err := targetTree.Diff(commitTree)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed diffing target branch and latest commit")
|
||||
}
|
||||
|
||||
log.Printf("There are %d changes:", changes.Len())
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func getBranchTree(repo *git.Repository, name string) (*object.Tree, error) {
|
||||
refname := plumbing.NewRemoteReferenceName("origin", name)
|
||||
log.Printf("Treating target branch as: %s", refname)
|
||||
sha, err := repo.ResolveRevision(plumbing.Revision(refname))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed resolving branch %q", name)
|
||||
}
|
||||
|
||||
log.Printf("Branch %s resolves to %s", name, sha)
|
||||
|
||||
return getTreeForSHA(repo, *sha)
|
||||
}
|
||||
|
||||
func getCommitTree(repo *git.Repository, ref string) (*object.Tree, error) {
|
||||
sha, err := repo.ResolveRevision(plumbing.Revision(ref))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed resolving commit %q", ref)
|
||||
}
|
||||
|
||||
log.Printf("Ref %s resolves to %s", ref, sha)
|
||||
|
||||
return getTreeForSHA(repo, *sha)
|
||||
}
|
||||
|
||||
func getTreeForSHA(repo *git.Repository, sha plumbing.Hash) (*object.Tree, error) {
|
||||
commit, err := repo.CommitObject(sha)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed extracting commit %q", sha)
|
||||
}
|
||||
|
||||
tree, err := commit.Tree()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed getting commit %q worktree", sha)
|
||||
}
|
||||
|
||||
return tree, nil
|
||||
}
|
||||
|
||||
func getChangePath(c *object.Change) string {
|
||||
if c.From.Name != "" {
|
||||
return c.From.Name
|
||||
}
|
||||
|
||||
return c.To.Name
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
/*
|
||||
Copyright 2022 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package changes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestHasCodeChanges(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in Changes
|
||||
out bool
|
||||
}{
|
||||
{
|
||||
name: "Only docs changes",
|
||||
in: Changes{Docs: true},
|
||||
out: false,
|
||||
},
|
||||
{
|
||||
name: "Only Go changes",
|
||||
in: Changes{Code: true},
|
||||
out: true,
|
||||
},
|
||||
{
|
||||
name: "Helm and docs changes",
|
||||
in: Changes{Docs: true, Helm: true},
|
||||
out: true,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
require.Equal(t, test.out, test.in.HasCodeChanges())
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package customflag
|
||||
|
||||
import "strings"
|
||||
|
||||
type StringArray []string
|
||||
|
||||
func (flags StringArray) String() string {
|
||||
return strings.Join(flags, ", ")
|
||||
}
|
||||
|
||||
func (flags *StringArray) Set(value string) error {
|
||||
*flags = append(*flags, value)
|
||||
return nil
|
||||
}
|
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 Gravitational, Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
package etcd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
metricsURL = "https://127.0.0.1:3379"
|
||||
)
|
||||
|
||||
type Instance struct {
|
||||
process *exec.Cmd
|
||||
dataDir string
|
||||
kill context.CancelFunc
|
||||
stdout bytes.Buffer
|
||||
stderr bytes.Buffer
|
||||
}
|
||||
|
||||
func (etcd *Instance) Stop() {
|
||||
log.Printf("Killing etcd process")
|
||||
etcd.kill()
|
||||
|
||||
log.Printf("Waiting for etcd process to exit...")
|
||||
switch err := etcd.process.Wait().(type) {
|
||||
case nil:
|
||||
break
|
||||
|
||||
case *exec.ExitError:
|
||||
// we expect a return code of -1 because we've just killed the process
|
||||
// above. If we get something else then etcd failed earlier for some
|
||||
// reason and we should print diagnostic output
|
||||
if err.ExitCode() != -1 {
|
||||
log.Printf("Etcd exited with unexpected status %d", err.ExitCode())
|
||||
log.Printf("stderr:\n%s", etcd.stderr.String())
|
||||
}
|
||||
|
||||
default:
|
||||
log.Printf("Failed: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Removing data dir")
|
||||
if err := os.RemoveAll(etcd.dataDir); err != nil {
|
||||
log.Printf("Failed removing data dir: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the etcd server using the keys extpected by the
|
||||
// integration and unit tests
|
||||
func Start(ctx context.Context, workspace string, env ...string) (*Instance, error) {
|
||||
etcdBinary, err := exec.LookPath("etcd")
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "can't find etcd binary")
|
||||
}
|
||||
|
||||
dataDir, err := os.MkdirTemp(os.TempDir(), "teleport-etcd-*")
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "can't create temp dir")
|
||||
}
|
||||
|
||||
certsDir := path.Join(workspace, "examples", "etcd", "certs")
|
||||
|
||||
etcdInstance := &Instance{}
|
||||
var processCtx context.Context
|
||||
processCtx, etcdInstance.kill = context.WithCancel(context.Background())
|
||||
|
||||
etcdInstance.process = exec.CommandContext(processCtx, etcdBinary,
|
||||
"--name", "teleportstorage",
|
||||
"--data-dir", dataDir,
|
||||
"--initial-cluster-state", "new",
|
||||
"--cert-file", path.Join(certsDir, "server-cert.pem"),
|
||||
"--key-file", path.Join(certsDir, "server-key.pem"),
|
||||
"--trusted-ca-file", path.Join(certsDir, "ca-cert.pem"),
|
||||
"--advertise-client-urls=https://127.0.0.1:2379",
|
||||
"--listen-client-urls=https://127.0.0.1:2379",
|
||||
"--listen-metrics-urls", metricsURL,
|
||||
"--client-cert-auth",
|
||||
)
|
||||
etcdInstance.process.Dir = workspace
|
||||
etcdInstance.process.Stdout = &etcdInstance.stdout
|
||||
etcdInstance.process.Stderr = &etcdInstance.stderr
|
||||
|
||||
if len(env) > 0 {
|
||||
etcdInstance.process.Env = append(os.Environ(), env...)
|
||||
}
|
||||
|
||||
log.Printf("Launching etcd (%s)", etcdInstance.process.Path)
|
||||
if err = etcdInstance.process.Start(); err != nil {
|
||||
return nil, trace.Wrap(err, "failed starting etcd")
|
||||
}
|
||||
|
||||
timeoutCtx, cancelTimeout := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancelTimeout()
|
||||
|
||||
if err := waitForEtcdToStart(timeoutCtx, certsDir); err != nil {
|
||||
log.Printf("Etcd failed to come up. Tidying up.")
|
||||
etcdInstance.Stop()
|
||||
return nil, trace.Wrap(err, "failed while waiting for etcd to start")
|
||||
}
|
||||
|
||||
return etcdInstance, nil
|
||||
}
|
||||
|
||||
// waitForEtcdToStart polls an etcd server (as started with Start()) until either
|
||||
// a) the etcd service reports itself as healthy, or
|
||||
// b) the supplied context expires
|
||||
func waitForEtcdToStart(ctx context.Context, certDir string) error {
|
||||
log.Printf("Waiting for etcd to come up...")
|
||||
|
||||
ticker := time.NewTicker(100 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
client, err := newHTTPSTransport(certDir)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed to create https client")
|
||||
}
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
healthy, err := pollForHealth(ctx, client, metricsURL+"/health")
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
if healthy {
|
||||
log.Printf("Etcd reporting healthy")
|
||||
return nil
|
||||
}
|
||||
|
||||
case <-ctx.Done():
|
||||
return trace.Errorf("timed out waiting for etcd to start")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// newHTTPSTransport creates an HTTP client configured to use TLS with an etcd server
|
||||
// as started with Start()
|
||||
func newHTTPSTransport(certDir string) (*http.Client, error) {
|
||||
caCertPath := path.Join(certDir, "ca-cert.pem")
|
||||
caCert, err := os.ReadFile(caCertPath)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed reading CA cert from %s", caCertPath)
|
||||
}
|
||||
|
||||
clientCert, err := tls.LoadX509KeyPair(
|
||||
path.Join(certDir, "client-cert.pem"), path.Join(certDir, "client-key.pem"))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed reading client cert")
|
||||
}
|
||||
|
||||
transport := http.DefaultTransport.(*http.Transport).Clone()
|
||||
transport.TLSClientConfig.RootCAs = x509.NewCertPool()
|
||||
if !transport.TLSClientConfig.RootCAs.AppendCertsFromPEM(caCert) {
|
||||
return nil, trace.Errorf("Failed adding CA cert")
|
||||
}
|
||||
transport.TLSClientConfig.Certificates = []tls.Certificate{clientCert}
|
||||
|
||||
return &http.Client{Transport: transport}, nil
|
||||
}
|
||||
|
||||
// pollForHealth polls the etcd metrecs endpoint for status information, returning
|
||||
// true if the service reports itself as healthy
|
||||
func pollForHealth(ctx context.Context, client *http.Client, url string) (bool, error) {
|
||||
type health struct {
|
||||
Health string `json:"health"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
timeoutCtx, cancel := context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
request, err := http.NewRequestWithContext(timeoutCtx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err, "Failed constructing poll request")
|
||||
}
|
||||
|
||||
// A request failure is considered "not healthy" rather than an error, as
|
||||
// the etcd server may just not be up yet.
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
return false, nil
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return false, trace.Wrap(err, "failed reading poll response body")
|
||||
}
|
||||
|
||||
status := health{}
|
||||
if err = json.Unmarshal(body, &status); err != nil {
|
||||
return false, trace.Wrap(err, "failed parsing poll response")
|
||||
}
|
||||
|
||||
return status.Health == "true", nil
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/gravitational/teleport/.cloudbuild/scripts/internal/github"
|
||||
)
|
||||
|
||||
// Config represents a git repository that has been configured to use a
|
||||
// deployment key, and acts as a handle to the resources so that we can
|
||||
// clean them up when we're done.
|
||||
type Config struct {
|
||||
identity string
|
||||
knownHosts string
|
||||
repoDir string
|
||||
}
|
||||
|
||||
// Configure alters the configuration of the git repository in `repoDir`
|
||||
// so that we can access it from build. If `deployKey` is non-nil the repo
|
||||
// will be configured to use that. If no deploy key is supplied, the repository
|
||||
// config is untouched.
|
||||
func Configure(ctx context.Context, repoDir string, deployKey []byte) (cfg *Config, err error) {
|
||||
var identity string
|
||||
var hostsFile string
|
||||
|
||||
// The deploy key we're using is too sensitive to just hope that every
|
||||
// exit path will clean it up on failure, so let's just register a
|
||||
// cleanup function now just in case.
|
||||
defer func() {
|
||||
if err != nil {
|
||||
cleanup(identity, hostsFile)
|
||||
}
|
||||
}()
|
||||
|
||||
// If we have been supplied with deployment key, then we need to use that
|
||||
// to access the repository. This implies that need to use ssh to read from
|
||||
// the remote, so we will have to deal with known_hosts, etc.
|
||||
if deployKey != nil {
|
||||
githubHostKeys, err := getGithubHostKeys(ctx)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed configuring known hosts")
|
||||
}
|
||||
|
||||
// configure SSH known_hosts for github.com
|
||||
hostsFile, err = configureKnownHosts("github.com", githubHostKeys)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed configuring known hosts")
|
||||
}
|
||||
|
||||
// GCB clones via https, and our deploy key won't work with that, so
|
||||
// force git to access the remote over ssh with a rewrite rule
|
||||
log.Info("Adding remote url rewrite rule")
|
||||
err = git(ctx, repoDir, "config", `url.git@github.com:.insteadOf`, "https://github.com/")
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed configuring url rewrite rule")
|
||||
}
|
||||
|
||||
// set up the identity for the deploy key
|
||||
identity, err = writeKey(deployKey)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed configuring SSH identity")
|
||||
}
|
||||
|
||||
// finally, force git to
|
||||
// a) use our custom SSH setup when accessing the remote, and
|
||||
// b) fail if the github host tries to present a host key other than
|
||||
// one we got from the metadata service
|
||||
log.Infof("Configuring git ssh command")
|
||||
err = git(ctx, repoDir, "config", "core.sshCommand",
|
||||
fmt.Sprintf("ssh -i %s -o StrictHostKeyChecking=yes -o UserKnownHostsFile=%s", identity, hostsFile))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed configuring git to use deploy key")
|
||||
}
|
||||
}
|
||||
|
||||
return &Config{identity: identity, repoDir: repoDir, knownHosts: hostsFile}, nil
|
||||
}
|
||||
|
||||
// Do runs `git args...` in the configured repository
|
||||
func (cfg *Config) Do(ctx context.Context, args ...string) error {
|
||||
return git(ctx, cfg.repoDir, args...)
|
||||
}
|
||||
|
||||
// Close cleans up the repository, including deleting the deployment key (if any)
|
||||
func (cfg *Config) Close() error {
|
||||
cleanup(cfg.identity, cfg.knownHosts)
|
||||
return nil
|
||||
}
|
||||
|
||||
func run(ctx context.Context, workingDir string, env []string, cmd string, args ...string) error {
|
||||
p := exec.CommandContext(ctx, cmd, args...)
|
||||
if len(env) != 0 {
|
||||
p.Env = append(os.Environ(), env...)
|
||||
}
|
||||
p.Dir = workingDir
|
||||
|
||||
cmdLogger := log.WithField("cmd", cmd)
|
||||
p.Stdout = cmdLogger.WriterLevel(log.InfoLevel)
|
||||
p.Stderr = cmdLogger.WriterLevel(log.ErrorLevel)
|
||||
return p.Run()
|
||||
}
|
||||
|
||||
func git(ctx context.Context, repoDir string, args ...string) error {
|
||||
return run(ctx, repoDir, nil, "/usr/bin/git", args...)
|
||||
}
|
||||
|
||||
func cleanup(deployKey, knownHosts string) {
|
||||
if knownHosts != "" {
|
||||
log.Infof("Removing known_hosts file %s", knownHosts)
|
||||
if err := os.Remove(knownHosts); err != nil {
|
||||
log.WithError(err).Error("Failed cleaning up known_hosts key")
|
||||
}
|
||||
}
|
||||
|
||||
if deployKey != "" {
|
||||
log.Infof("Removing deploy key file %s", deployKey)
|
||||
if err := os.Remove(deployKey); err != nil {
|
||||
log.WithError(err).Error("Failed cleaning up deploy key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// getGithubHostKeys fetches the github host keys from the github metadata
|
||||
// service. The metadata is fetched over HTTPS, and so we have built-on
|
||||
// protection against MitM attacks while fetching the expected host keys.
|
||||
func getGithubHostKeys(ctx context.Context) ([]ssh.PublicKey, error) {
|
||||
metadata, err := github.GetMetadata(ctx)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed fetching github metadata")
|
||||
}
|
||||
|
||||
// extract the host keys
|
||||
githubHostKeys, err := metadata.HostKeys()
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed fetching github hostKeys")
|
||||
}
|
||||
|
||||
return githubHostKeys, nil
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func writeKey(deployKey []byte) (string, error) {
|
||||
// Note that tempfiles are automatically created with 0600, so no-one else
|
||||
// should be able to read this.
|
||||
keyFile, err := os.CreateTemp("", "*")
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err, "failed creating keyfile")
|
||||
}
|
||||
defer keyFile.Close()
|
||||
|
||||
log.Infof("Writing deploy key to %s", keyFile.Name())
|
||||
_, err = keyFile.Write(deployKey)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err, "failed writing deploy key")
|
||||
}
|
||||
|
||||
// ensure there is a trailing newline in the key, as older versions of the
|
||||
// `ssh` client will barf on a key that doesn't have one, but will happily
|
||||
// allow multiples
|
||||
_, err = keyFile.WriteString("\n")
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err, "failed formatting key")
|
||||
}
|
||||
|
||||
return keyFile.Name(), nil
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"golang.org/x/crypto/ssh/knownhosts"
|
||||
)
|
||||
|
||||
func configureKnownHosts(hostname string, keys []ssh.PublicKey) (string, error) {
|
||||
knownHostsFile, err := os.CreateTemp("", "*")
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err, "failed creating known hosts file")
|
||||
}
|
||||
defer knownHostsFile.Close()
|
||||
|
||||
log.Infof("Writing known_hosts file to %s", knownHostsFile.Name())
|
||||
|
||||
addrs := []string{hostname}
|
||||
for _, k := range keys {
|
||||
log.Infof("processing key %s...", k.Type())
|
||||
_, err := knownHostsFile.WriteString(knownhosts.Line(addrs, k) + "\n")
|
||||
if err != nil {
|
||||
knownHostsFile.Close()
|
||||
os.Remove(knownHostsFile.Name())
|
||||
return "", trace.Wrap(err, "failed writing known hosts")
|
||||
}
|
||||
}
|
||||
|
||||
return knownHostsFile.Name(), nil
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package git
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func UnshallowRepository(ctx context.Context, workspace string, deployKey []byte) error {
|
||||
log.Info("Configuring git")
|
||||
gitCfg, err := Configure(ctx, workspace, deployKey)
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "failed configuring git")
|
||||
}
|
||||
defer gitCfg.Close()
|
||||
|
||||
log.Info("Unshallowing repository")
|
||||
err = gitCfg.Do(ctx, "fetch", "--unshallow")
|
||||
if err != nil {
|
||||
return trace.Wrap(err, "unshallow failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
const (
|
||||
metadataURL = "https://api.github.com/meta"
|
||||
)
|
||||
|
||||
// Metadata contains information about the github networking environment,
|
||||
// enclosing host keys for git/ssh access
|
||||
type Metadata struct {
|
||||
SSHKeyFingerPrints map[string]string `json:"ssh_key_fingerprints"`
|
||||
SSHKeys []string `json:"ssh_keys"`
|
||||
}
|
||||
|
||||
func GetMetadata(ctx context.Context) (*Metadata, error) {
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, metadataURL, nil)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed creating metadata request")
|
||||
}
|
||||
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed issuing metadata request")
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
if response.StatusCode != http.StatusOK {
|
||||
return nil, trace.Errorf("Metadata request failed %d", response.StatusCode)
|
||||
}
|
||||
|
||||
var meta Metadata
|
||||
err = json.NewDecoder(response.Body).Decode(&meta)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed parsing metadata")
|
||||
}
|
||||
|
||||
return &meta, nil
|
||||
}
|
||||
|
||||
func (meta *Metadata) HostKeys() ([]ssh.PublicKey, error) {
|
||||
keys := make([]ssh.PublicKey, 0, len(meta.SSHKeys))
|
||||
for _, text := range meta.SSHKeys {
|
||||
key, _, _, _, err := ssh.ParseAuthorizedKey([]byte(text))
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed parsing host key")
|
||||
}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
return keys, nil
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package secrets
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
secretmanager "cloud.google.com/go/secretmanager/apiv1"
|
||||
"github.com/gravitational/trace"
|
||||
log "github.com/sirupsen/logrus"
|
||||
secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1"
|
||||
)
|
||||
|
||||
// Fetch goes and grabs a single secret from the Google Cloud secret manager
|
||||
func Fetch(ctx context.Context, resourceName string) ([]byte, error) {
|
||||
c, err := secretmanager.NewClient(ctx)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed creating SecretManager client")
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
log.Debugf("Fetching secret %s", resourceName)
|
||||
secret, err := c.AccessSecretVersion(ctx, &secretmanagerpb.AccessSecretVersionRequest{
|
||||
Name: resourceName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err, "failed fetching secret token")
|
||||
}
|
||||
|
||||
return secret.Payload.Data, nil
|
||||
}
|
||||
|
||||
// FetchString fetches a single secret from the Google Cloud secret manager and returns
|
||||
// it as a string.
|
||||
func FetchString(ctx context.Context, resourceName string) (string, error) {
|
||||
data, err := Fetch(ctx, resourceName)
|
||||
if err != nil {
|
||||
return "", trace.Wrap(err)
|
||||
}
|
||||
|
||||
return string(data), nil
|
||||
}
|
17
Makefile
17
Makefile
|
@ -590,7 +590,7 @@ tooling: $(RENDER_TESTS) $(DIFF_TEST)
|
|||
# Runs all Go/shell tests, called by CI/CD.
|
||||
#
|
||||
.PHONY: test
|
||||
test: test-helm test-sh test-ci test-api test-go test-rust test-operator
|
||||
test: test-helm test-sh test-api test-go test-rust test-operator
|
||||
|
||||
$(TEST_LOG_DIR):
|
||||
mkdir $(TEST_LOG_DIR)
|
||||
|
@ -679,14 +679,6 @@ test-go-chaos:
|
|||
| tee $(TEST_LOG_DIR)/chaos.json \
|
||||
| ${RENDER_TESTS}
|
||||
|
||||
# Runs ci scripts tests
|
||||
.PHONY: test-ci
|
||||
test-ci: $(TEST_LOG_DIR) $(RENDER_TESTS)
|
||||
(cd .cloudbuild/scripts && \
|
||||
go test -cover -json ./... \
|
||||
| tee $(TEST_LOG_DIR)/ci.json \
|
||||
| ${RENDER_TESTS})
|
||||
|
||||
#
|
||||
# Runs all Go tests except integration and chaos, called by CI/CD.
|
||||
#
|
||||
|
@ -784,7 +776,7 @@ integration-root: $(TEST_LOG_DIR) $(RENDER_TESTS)
|
|||
lint: lint-sh lint-helm lint-api lint-go lint-license lint-rust lint-tools lint-protos
|
||||
|
||||
.PHONY: lint-tools
|
||||
lint-tools: lint-build-tooling lint-ci-scripts lint-backport
|
||||
lint-tools: lint-build-tooling lint-backport
|
||||
|
||||
#
|
||||
# Runs the clippy linter on our rust modules
|
||||
|
@ -829,11 +821,6 @@ lint-backport: GO_LINT_FLAGS ?=
|
|||
lint-backport:
|
||||
cd assets/backport && golangci-lint run -c ../../.golangci.yml $(GO_LINT_FLAGS)
|
||||
|
||||
.PHONY: lint-ci-scripts
|
||||
lint-ci-scripts: GO_LINT_FLAGS ?=
|
||||
lint-ci-scripts:
|
||||
cd .cloudbuild/scripts/ && golangci-lint run -c ../../.golangci.yml $(GO_LINT_FLAGS)
|
||||
|
||||
# api is no longer part of the teleport package, so golangci-lint skips it by default
|
||||
.PHONY: lint-api
|
||||
lint-api: GO_LINT_API_FLAGS ?=
|
||||
|
|
2
e
2
e
|
@ -1 +1 @@
|
|||
Subproject commit 97d4d7f239e5b3317ec70285e02d636580412bcb
|
||||
Subproject commit a00182c0a5d30c89f02e9745d484e2961d83b889
|
Loading…
Reference in a new issue