remove gcp/gcpkms/gcs/spanner/stackdriver
This commit is contained in:
parent
6afd5d71a4
commit
faed4aa7af
|
@ -1,191 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package gcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/compute/metadata"
|
||||
credentials "cloud.google.com/go/iam/credentials/apiv1"
|
||||
"github.com/hashicorp/vault/api"
|
||||
credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
|
||||
)
|
||||
|
||||
type GCPAuth struct {
|
||||
roleName string
|
||||
mountPath string
|
||||
authType string
|
||||
serviceAccountEmail string
|
||||
}
|
||||
|
||||
var _ api.AuthMethod = (*GCPAuth)(nil)
|
||||
|
||||
type LoginOption func(a *GCPAuth) error
|
||||
|
||||
const (
|
||||
iamType = "iam"
|
||||
gceType = "gce"
|
||||
defaultMountPath = "gcp"
|
||||
defaultAuthType = gceType
|
||||
identityMetadataURL = "http://metadata/computeMetadata/v1/instance/service-accounts/default/identity"
|
||||
)
|
||||
|
||||
// NewGCPAuth initializes a new GCP auth method interface to be
|
||||
// passed as a parameter to the client.Auth().Login method.
|
||||
//
|
||||
// Supported options: WithMountPath, WithIAMAuth, WithGCEAuth
|
||||
func NewGCPAuth(roleName string, opts ...LoginOption) (*GCPAuth, error) {
|
||||
if roleName == "" {
|
||||
return nil, fmt.Errorf("no role name provided for login")
|
||||
}
|
||||
|
||||
a := &GCPAuth{
|
||||
mountPath: defaultMountPath,
|
||||
authType: defaultAuthType,
|
||||
roleName: roleName,
|
||||
}
|
||||
|
||||
// Loop through each option
|
||||
for _, opt := range opts {
|
||||
// Call the option giving the instantiated
|
||||
// *GCPAuth as the argument
|
||||
err := opt(a)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error with login option: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// return the modified auth struct instance
|
||||
return a, nil
|
||||
}
|
||||
|
||||
// Login sets up the required request body for the GCP auth method's /login
|
||||
// endpoint, and performs a write to it. This method defaults to the "gce"
|
||||
// auth type unless NewGCPAuth is called with WithIAMAuth().
|
||||
func (a *GCPAuth) Login(ctx context.Context, client *api.Client) (*api.Secret, error) {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
loginData := map[string]interface{}{
|
||||
"role": a.roleName,
|
||||
}
|
||||
switch a.authType {
|
||||
case gceType:
|
||||
jwt, err := a.getJWTFromMetadataService(client.Address())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to retrieve JWT from GCE metadata service: %w", err)
|
||||
}
|
||||
loginData["jwt"] = jwt
|
||||
case iamType:
|
||||
jwtResp, err := a.signJWT()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to sign JWT for authenticating to GCP: %w", err)
|
||||
}
|
||||
loginData["jwt"] = jwtResp.SignedJwt
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("auth/%s/login", a.mountPath)
|
||||
resp, err := client.Logical().WriteWithContext(ctx, path, loginData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to log in with GCP auth: %w", err)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func WithMountPath(mountPath string) LoginOption {
|
||||
return func(a *GCPAuth) error {
|
||||
a.mountPath = mountPath
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithIAMAuth(serviceAccountEmail string) LoginOption {
|
||||
return func(a *GCPAuth) error {
|
||||
a.serviceAccountEmail = serviceAccountEmail
|
||||
a.authType = iamType
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithGCEAuth() LoginOption {
|
||||
return func(a *GCPAuth) error {
|
||||
a.authType = gceType
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// generate signed JWT token from GCP IAM.
|
||||
func (a *GCPAuth) signJWT() (*credentialspb.SignJwtResponse, error) {
|
||||
ctx := context.Background()
|
||||
iamClient, err := credentials.NewIamCredentialsClient(ctx) // can pass option.WithCredentialsFile("path/to/creds.json") as second param if GOOGLE_APPLICATION_CREDENTIALS env var not set
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to initialize IAM credentials client: %w", err)
|
||||
}
|
||||
defer iamClient.Close()
|
||||
|
||||
resourceName := fmt.Sprintf("projects/-/serviceAccounts/%s", a.serviceAccountEmail)
|
||||
jwtPayload := map[string]interface{}{
|
||||
"aud": fmt.Sprintf("vault/%s", a.roleName),
|
||||
"sub": a.serviceAccountEmail,
|
||||
"exp": time.Now().Add(time.Minute * 10).Unix(),
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(jwtPayload)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to marshal jwt payload to json: %w", err)
|
||||
}
|
||||
|
||||
signJWTReq := &credentialspb.SignJwtRequest{
|
||||
Name: resourceName,
|
||||
Payload: string(payloadBytes),
|
||||
}
|
||||
|
||||
jwtResp, err := iamClient.SignJwt(ctx, signJWTReq)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to sign JWT: %w", err)
|
||||
}
|
||||
|
||||
return jwtResp, nil
|
||||
}
|
||||
|
||||
func (a *GCPAuth) getJWTFromMetadataService(vaultAddress string) (string, error) {
|
||||
if !metadata.OnGCE() {
|
||||
return "", fmt.Errorf("GCE metadata service not available")
|
||||
}
|
||||
|
||||
// build request to metadata server
|
||||
c := &http.Client{}
|
||||
req, err := http.NewRequest(http.MethodGet, identityMetadataURL, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error creating http request: %w", err)
|
||||
}
|
||||
|
||||
req.Header.Add("Metadata-Flavor", "Google")
|
||||
q := url.Values{}
|
||||
q.Add("audience", fmt.Sprintf("%s/vault/%s", vaultAddress, a.roleName))
|
||||
q.Add("format", "full")
|
||||
req.URL.RawQuery = q.Encode()
|
||||
resp, err := c.Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error making request to metadata service: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// get jwt from response
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
jwt := string(body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error reading response from metadata service: %w", err)
|
||||
}
|
||||
|
||||
return jwt, nil
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
module github.com/hashicorp/vault/api/auth/gcp
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.97.0
|
||||
github.com/hashicorp/vault/api v1.9.2
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0
|
||||
google.golang.org/grpc v1.41.0 // indirect
|
||||
)
|
|
@ -1,641 +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 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/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/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
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/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/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/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/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo=
|
||||
github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
||||
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
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/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/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 h1:6DWmvNpomjL1+3liNSZbVns3zsYzzCjm6pRBO1tLeso=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs=
|
||||
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
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/go-retryablehttp v0.6.6 h1:HJunrbHTDDbBb/ay4kxa1n+dLmttUlnP3V9oNE4hmsM=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ=
|
||||
github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts=
|
||||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc=
|
||||
github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/vault/api v1.9.2 h1:YjkZLJ7K3inKgMZ0wzCU9OHqc+UqMQyXsPXnf3Cl2as=
|
||||
github.com/hashicorp/vault/api v1.9.2/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8=
|
||||
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/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/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_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/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
|
||||
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
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/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
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-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-20190911031432-227b76d455e7/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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
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 h1:Qmd2pbz05z7z6lm0DrgQVVPuBm92jqujBKMHMOlOQEw=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-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-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-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-20210615035016-665e8c7367d1/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-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/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/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
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.57.0 h1:4t9zuDlHLcIx0ZEhmXEeFVCRsiOgpgn2QOH9N0MNjPI=
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
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-20210924002016-3dee208752a0 h1:5Tbluzus3QxoAJx4IefGt1W0HQZW4nuMrVk684jI74Q=
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
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.41.0 h1:f+PlOh7QV4iIJkPrx5NQ7qaNGFQ3OTse67yaDHfju4E=
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
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.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,236 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package gcp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
||||
"github.com/hashicorp/go-gcp-common/gcputil"
|
||||
hclog "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth"
|
||||
"golang.org/x/oauth2"
|
||||
"google.golang.org/api/iamcredentials/v1"
|
||||
)
|
||||
|
||||
const (
|
||||
typeGCE = "gce"
|
||||
typeIAM = "iam"
|
||||
identityEndpoint = "http://metadata/computeMetadata/v1/instance/service-accounts/%s/identity"
|
||||
defaultIamMaxJwtExpMinutes = 15
|
||||
)
|
||||
|
||||
type gcpMethod struct {
|
||||
logger hclog.Logger
|
||||
authType string
|
||||
mountPath string
|
||||
role string
|
||||
credentials string
|
||||
serviceAccount string
|
||||
project string
|
||||
jwtExp int64
|
||||
}
|
||||
|
||||
func NewGCPAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
|
||||
if conf == nil {
|
||||
return nil, errors.New("empty config")
|
||||
}
|
||||
if conf.Config == nil {
|
||||
return nil, errors.New("empty config data")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
g := &gcpMethod{
|
||||
logger: conf.Logger,
|
||||
mountPath: conf.MountPath,
|
||||
serviceAccount: "default",
|
||||
}
|
||||
|
||||
typeRaw, ok := conf.Config["type"]
|
||||
if !ok {
|
||||
return nil, errors.New("missing 'type' value")
|
||||
}
|
||||
g.authType, ok = typeRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert 'type' config value to string")
|
||||
}
|
||||
|
||||
roleRaw, ok := conf.Config["role"]
|
||||
if !ok {
|
||||
return nil, errors.New("missing 'role' value")
|
||||
}
|
||||
g.role, ok = roleRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert 'role' config value to string")
|
||||
}
|
||||
|
||||
switch {
|
||||
case g.role == "":
|
||||
return nil, errors.New("'role' value is empty")
|
||||
case g.authType == "":
|
||||
return nil, errors.New("'type' value is empty")
|
||||
case g.authType != typeGCE && g.authType != typeIAM:
|
||||
return nil, errors.New("'type' value is invalid")
|
||||
}
|
||||
|
||||
credentialsRaw, ok := conf.Config["credentials"]
|
||||
if ok {
|
||||
g.credentials, ok = credentialsRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert 'credentials' value into string")
|
||||
}
|
||||
}
|
||||
|
||||
serviceAccountRaw, ok := conf.Config["service_account"]
|
||||
if ok {
|
||||
g.serviceAccount, ok = serviceAccountRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert 'service_account' value into string")
|
||||
}
|
||||
}
|
||||
|
||||
projectRaw, ok := conf.Config["project"]
|
||||
if ok {
|
||||
g.project, ok = projectRaw.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("could not convert 'project' value into string")
|
||||
}
|
||||
}
|
||||
|
||||
jwtExpRaw, ok := conf.Config["jwt_exp"]
|
||||
if ok {
|
||||
g.jwtExp, err = parseutil.ParseInt(jwtExpRaw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error parsing 'jwt_raw' into integer: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *gcpMethod) Authenticate(ctx context.Context, client *api.Client) (retPath string, header http.Header, retData map[string]interface{}, retErr error) {
|
||||
g.logger.Trace("beginning authentication")
|
||||
|
||||
data := make(map[string]interface{})
|
||||
var jwt string
|
||||
|
||||
switch g.authType {
|
||||
case typeGCE:
|
||||
httpClient := cleanhttp.DefaultClient()
|
||||
|
||||
// Fetch token
|
||||
{
|
||||
req, err := http.NewRequest("GET", fmt.Sprintf(identityEndpoint, g.serviceAccount), nil)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("error creating request: %w", err)
|
||||
return
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
req.Header.Add("Metadata-Flavor", "Google")
|
||||
q := req.URL.Query()
|
||||
q.Add("audience", fmt.Sprintf("%s/vault/%s", client.Address(), g.role))
|
||||
q.Add("format", "full")
|
||||
req.URL.RawQuery = q.Encode()
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("error fetching instance token: %w", err)
|
||||
return
|
||||
}
|
||||
if resp == nil {
|
||||
retErr = errors.New("empty response fetching instance toke")
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
jwtBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("error reading instance token response body: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
jwt = string(jwtBytes)
|
||||
}
|
||||
|
||||
default:
|
||||
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, cleanhttp.DefaultClient())
|
||||
|
||||
credentials, tokenSource, err := gcputil.FindCredentials(g.credentials, ctx, iamcredentials.CloudPlatformScope)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("could not obtain credentials: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
httpClient := oauth2.NewClient(ctx, tokenSource)
|
||||
|
||||
var serviceAccount string
|
||||
if g.serviceAccount == "" && credentials != nil {
|
||||
serviceAccount = credentials.ClientEmail
|
||||
} else {
|
||||
serviceAccount = g.serviceAccount
|
||||
}
|
||||
if serviceAccount == "" {
|
||||
retErr = errors.New("could not obtain service account from credentials (possibly Application Default Credentials are being used); a service account to authenticate as must be provided")
|
||||
return
|
||||
}
|
||||
|
||||
ttlMin := int64(defaultIamMaxJwtExpMinutes)
|
||||
if g.jwtExp != 0 {
|
||||
ttlMin = g.jwtExp
|
||||
}
|
||||
ttl := time.Minute * time.Duration(ttlMin)
|
||||
|
||||
jwtPayload := map[string]interface{}{
|
||||
"aud": fmt.Sprintf("http://vault/%s", g.role),
|
||||
"sub": serviceAccount,
|
||||
"exp": time.Now().Add(ttl).Unix(),
|
||||
}
|
||||
payloadBytes, err := json.Marshal(jwtPayload)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("could not convert JWT payload to JSON string: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
jwtReq := &iamcredentials.SignJwtRequest{
|
||||
Payload: string(payloadBytes),
|
||||
}
|
||||
|
||||
iamClient, err := iamcredentials.New(httpClient)
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("could not create IAM client: %w", err)
|
||||
return
|
||||
}
|
||||
|
||||
resourceName := fmt.Sprintf("projects/-/serviceAccounts/%s", serviceAccount)
|
||||
resp, err := iamClient.Projects.ServiceAccounts.SignJwt(resourceName, jwtReq).Do()
|
||||
if err != nil {
|
||||
retErr = fmt.Errorf("unable to sign JWT for %s using given Vault credentials: %w", resourceName, err)
|
||||
return
|
||||
}
|
||||
|
||||
jwt = resp.SignedJwt
|
||||
}
|
||||
|
||||
data["role"] = g.role
|
||||
data["jwt"] = jwt
|
||||
|
||||
return fmt.Sprintf("%s/login", g.mountPath), nil, data, nil
|
||||
}
|
||||
|
||||
func (g *gcpMethod) NewCreds() chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *gcpMethod) CredSuccess() {
|
||||
}
|
||||
|
||||
func (g *gcpMethod) Shutdown() {
|
||||
}
|
|
@ -16,7 +16,6 @@ import (
|
|||
"github.com/hashicorp/vault/command/agentproxyshared/auth/approle"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/cert"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/cf"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/gcp"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/jwt"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/kerberos"
|
||||
"github.com/hashicorp/vault/command/agentproxyshared/auth/kubernetes"
|
||||
|
@ -37,8 +36,6 @@ func GetAutoAuthMethodFromConfig(autoAuthMethodType string, authConfig *auth.Aut
|
|||
return cert.NewCertAuthMethod(authConfig)
|
||||
case "cf":
|
||||
return cf.NewCFAuthMethod(authConfig)
|
||||
case "gcp":
|
||||
return gcp.NewGCPAuthMethod(authConfig)
|
||||
case "jwt":
|
||||
return jwt.NewJWTAuthMethod(authConfig)
|
||||
case "kerberos":
|
||||
|
|
|
@ -106,7 +106,6 @@ func (b *BaseCommand) PredictVaultAvailableAuths() complete.Predictor {
|
|||
"app-id",
|
||||
"approle",
|
||||
"cert",
|
||||
"gcp",
|
||||
"github",
|
||||
"ldap",
|
||||
"okta",
|
||||
|
|
|
@ -28,7 +28,6 @@ import (
|
|||
|
||||
credCentrify "github.com/hashicorp/vault-plugin-auth-centrify"
|
||||
credCF "github.com/hashicorp/vault-plugin-auth-cf"
|
||||
credGcp "github.com/hashicorp/vault-plugin-auth-gcp/plugin"
|
||||
credOIDC "github.com/hashicorp/vault-plugin-auth-jwt"
|
||||
credKerb "github.com/hashicorp/vault-plugin-auth-kerberos"
|
||||
credOCI "github.com/hashicorp/vault-plugin-auth-oci"
|
||||
|
@ -49,13 +48,11 @@ import (
|
|||
physCouchDB "github.com/hashicorp/vault/physical/couchdb"
|
||||
physEtcd "github.com/hashicorp/vault/physical/etcd"
|
||||
physFoundationDB "github.com/hashicorp/vault/physical/foundationdb"
|
||||
physGCS "github.com/hashicorp/vault/physical/gcs"
|
||||
physManta "github.com/hashicorp/vault/physical/manta"
|
||||
physMySQL "github.com/hashicorp/vault/physical/mysql"
|
||||
physOCI "github.com/hashicorp/vault/physical/oci"
|
||||
physPostgreSQL "github.com/hashicorp/vault/physical/postgresql"
|
||||
physRaft "github.com/hashicorp/vault/physical/raft"
|
||||
physSpanner "github.com/hashicorp/vault/physical/spanner"
|
||||
physSwift "github.com/hashicorp/vault/physical/swift"
|
||||
physZooKeeper "github.com/hashicorp/vault/physical/zookeeper"
|
||||
physFile "github.com/hashicorp/vault/sdk/physical/file"
|
||||
|
@ -188,7 +185,6 @@ var (
|
|||
"file_transactional": physFile.NewTransactionalFileBackend,
|
||||
"file": physFile.NewFileBackend,
|
||||
"foundationdb": physFoundationDB.NewFDBBackend,
|
||||
"gcs": physGCS.NewBackend,
|
||||
"inmem_ha": physInmem.NewInmemHA,
|
||||
"inmem_transactional_ha": physInmem.NewTransactionalInmemHA,
|
||||
"inmem_transactional": physInmem.NewTransactionalInmem,
|
||||
|
@ -197,7 +193,6 @@ var (
|
|||
"mysql": physMySQL.NewMySQLBackend,
|
||||
"oci": physOCI.NewBackend,
|
||||
"postgresql": physPostgreSQL.NewPostgreSQLBackend,
|
||||
"spanner": physSpanner.NewBackend,
|
||||
"swift": physSwift.NewSwiftBackend,
|
||||
"raft": physRaft.NewRaftBackend,
|
||||
"zookeeper": physZooKeeper.NewZooKeeperBackend,
|
||||
|
@ -216,7 +211,6 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) map[string]cli.Co
|
|||
"centrify": &credCentrify.CLIHandler{},
|
||||
"cert": &credCert.CLIHandler{},
|
||||
"cf": &credCF.CLIHandler{},
|
||||
"gcp": &credGcp.CLIHandler{},
|
||||
"github": &credGitHub.CLIHandler{},
|
||||
"kerberos": &credKerb.CLIHandler{},
|
||||
"ldap": &credLdap.CLIHandler{},
|
||||
|
|
|
@ -270,19 +270,6 @@ func (c *OperatorDiagnoseCommand) offlineDiagnostics(ctx context.Context) error
|
|||
if len(t.DogStatsDTags) > 0 && t.DogStatsDAddr == "" {
|
||||
return errors.New("incomplete DogStatsD telemetry configuration, missing dogstatsd_addr, while dogstatsd_tags specified")
|
||||
}
|
||||
|
||||
// If any Stackdriver setting is present but we're missing the basic fields...
|
||||
if coalesce(t.StackdriverNamespace, t.StackdriverLocation, t.StackdriverDebugLogs, t.StackdriverNamespace) != nil {
|
||||
if t.StackdriverProjectID == "" {
|
||||
return errors.New("incomplete Stackdriver telemetry configuration, missing stackdriver_project_id")
|
||||
}
|
||||
if t.StackdriverLocation == "" {
|
||||
return errors.New("incomplete Stackdriver telemetry configuration, missing stackdriver_location")
|
||||
}
|
||||
if t.StackdriverNamespace == "" {
|
||||
return errors.New("incomplete Stackdriver telemetry configuration, missing stackdriver_namespace")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
|
|
@ -831,10 +831,6 @@ func testConfig_Sanitized(t *testing.T) {
|
|||
"dogstatsd_addr": "",
|
||||
"dogstatsd_tags": []string(nil),
|
||||
"prometheus_retention_time": 24 * time.Hour,
|
||||
"stackdriver_location": "",
|
||||
"stackdriver_namespace": "",
|
||||
"stackdriver_project_id": "",
|
||||
"stackdriver_debug_logs": false,
|
||||
"statsd_address": "bar",
|
||||
"statsite_address": "",
|
||||
"lease_metrics_epsilon": time.Hour,
|
||||
|
|
22
go.mod
22
go.mod
|
@ -25,9 +25,6 @@ replace github.com/hashicorp/vault/api/auth/userpass => ./api/auth/userpass
|
|||
replace github.com/hashicorp/vault/sdk => ./sdk
|
||||
|
||||
require (
|
||||
cloud.google.com/go/monitoring v1.17.0
|
||||
cloud.google.com/go/spanner v1.54.0
|
||||
cloud.google.com/go/storage v1.30.1
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230626094100-7e9e0395ebec
|
||||
github.com/aerospike/aerospike-client-go/v5 v5.6.0
|
||||
github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2
|
||||
|
@ -56,7 +53,6 @@ require (
|
|||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-github v17.0.0+incompatible
|
||||
github.com/google/go-metrics-stackdriver v0.2.0
|
||||
github.com/google/tink/go v1.7.0
|
||||
github.com/hashicorp-forge/bbolt v1.3.8-hc3
|
||||
github.com/hashicorp/cap v0.3.0
|
||||
|
@ -66,13 +62,11 @@ require (
|
|||
github.com/hashicorp/eventlogger v0.2.1
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192
|
||||
github.com/hashicorp/go-gcp-common v0.8.0
|
||||
github.com/hashicorp/go-hclog v1.5.0
|
||||
github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.10
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.8
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.7
|
||||
github.com/hashicorp/go-memdb v1.3.4
|
||||
|
@ -110,15 +104,12 @@ require (
|
|||
github.com/hashicorp/raft-snapshot v1.0.4
|
||||
github.com/hashicorp/vault-plugin-auth-centrify v0.15.1
|
||||
github.com/hashicorp/vault-plugin-auth-cf v0.15.0
|
||||
github.com/hashicorp/vault-plugin-auth-gcp v0.16.0
|
||||
github.com/hashicorp/vault-plugin-auth-jwt v0.16.1
|
||||
github.com/hashicorp/vault-plugin-auth-kerberos v0.10.0
|
||||
github.com/hashicorp/vault-plugin-auth-kubernetes v0.16.0
|
||||
github.com/hashicorp/vault-plugin-auth-oci v0.14.0
|
||||
github.com/hashicorp/vault-plugin-mock v0.16.1
|
||||
github.com/hashicorp/vault-plugin-secrets-ad v0.16.0
|
||||
github.com/hashicorp/vault-plugin-secrets-gcp v0.16.0
|
||||
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.15.0
|
||||
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.5.0
|
||||
github.com/hashicorp/vault-plugin-secrets-kv v0.15.0
|
||||
github.com/hashicorp/vault-plugin-secrets-openldap v0.11.1
|
||||
|
@ -188,7 +179,6 @@ require (
|
|||
golang.org/x/term v0.20.0
|
||||
golang.org/x/text v0.15.0
|
||||
golang.org/x/tools v0.18.0
|
||||
google.golang.org/api v0.163.0
|
||||
google.golang.org/grpc v1.61.1
|
||||
google.golang.org/protobuf v1.34.1
|
||||
gopkg.in/ory-am/dockertest.v3 v3.3.4
|
||||
|
@ -198,11 +188,8 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.111.0 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/kms v1.15.5 // indirect
|
||||
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect
|
||||
github.com/Azure/azure-sdk-for-go v67.2.0+incompatible // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
|
@ -235,15 +222,12 @@ require (
|
|||
github.com/boombuler/barcode v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect
|
||||
github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect
|
||||
github.com/circonus-labs/circonusllhist v0.1.3 // indirect
|
||||
github.com/cloudflare/circl v1.3.7 // indirect
|
||||
github.com/cloudfoundry-community/go-cfclient v0.0.0-20210823134051-721f0e559306 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 // indirect
|
||||
github.com/containerd/containerd v1.7.12 // indirect
|
||||
github.com/containerd/continuity v0.4.2 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
|
@ -263,8 +247,6 @@ require (
|
|||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.11.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gammazero/deque v0.2.1 // indirect
|
||||
|
@ -328,7 +310,6 @@ require (
|
|||
github.com/jcmturner/gofork v1.7.6 // indirect
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 // indirect
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
|
||||
github.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
|
@ -387,14 +368,13 @@ require (
|
|||
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
|
||||
go.mongodb.org/mongo-driver v1.11.6 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.22.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.19.1 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.163.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240102182953-50ed04b92917 // indirect
|
||||
|
|
44
go.sum
44
go.sum
|
@ -3,7 +3,6 @@ bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh
|
|||
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.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts=
|
||||
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.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
|
@ -44,8 +43,6 @@ cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5x
|
|||
cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk=
|
||||
cloud.google.com/go v0.111.0 h1:YHLKNupSD1KqjDbQ3+LVdQ81h/UJbJyZG203cEfnQgM=
|
||||
cloud.google.com/go v0.111.0/go.mod h1:0mibmpKP1TyOOFYQY5izo0LnT+ecvOQ0Sg3OdmMiNRU=
|
||||
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
|
||||
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
|
||||
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
|
||||
|
@ -426,8 +423,6 @@ cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBa
|
|||
cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk=
|
||||
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||
cloud.google.com/go/iam v1.1.2/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=
|
||||
cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=
|
||||
cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=
|
||||
|
@ -455,8 +450,6 @@ cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+z
|
|||
cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
|
||||
cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
|
||||
cloud.google.com/go/kms v1.15.2/go.mod h1:3hopT4+7ooWRCjc2DxgnpESFxhIraaI2IpAVUEhbT/w=
|
||||
cloud.google.com/go/kms v1.15.5 h1:pj1sRfut2eRbD9pFRjNnPNg/CzJPuQAzUujMIM1vVeM=
|
||||
cloud.google.com/go/kms v1.15.5/go.mod h1:cU2H5jnp6G2TDpUGZyqTCoy1n16fbubHZjmVXSMtwDI=
|
||||
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
|
||||
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
|
||||
cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=
|
||||
|
@ -477,8 +470,6 @@ cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+
|
|||
cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ=
|
||||
cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc=
|
||||
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
|
||||
cloud.google.com/go/longrunning v0.5.4 h1:w8xEcbZodnA2BbW6sVirkkoC+1gP8wS57EUUgGS0GVg=
|
||||
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
||||
cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=
|
||||
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
|
||||
cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
|
||||
|
@ -511,8 +502,6 @@ cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtD
|
|||
cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
|
||||
cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM=
|
||||
cloud.google.com/go/monitoring v1.16.0/go.mod h1:Ptp15HgAyM1fNICAojDMoNc/wUmn67mLHQfyqbw+poY=
|
||||
cloud.google.com/go/monitoring v1.17.0 h1:blrdvF0MkPPivSO041ihul7rFMhXdVp8Uq7F59DKXTU=
|
||||
cloud.google.com/go/monitoring v1.17.0/go.mod h1:KwSsX5+8PnXv5NJnICZzW2R8pWTis8ypC4zmdRD63Tw=
|
||||
cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
|
||||
cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
|
||||
cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=
|
||||
|
@ -700,8 +689,6 @@ cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63wh
|
|||
cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=
|
||||
cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI=
|
||||
cloud.google.com/go/spanner v1.49.0/go.mod h1:eGj9mQGK8+hkgSVbHNQ06pQ4oS+cyc4tXXd6Dif1KoM=
|
||||
cloud.google.com/go/spanner v1.54.0 h1:ttU+lhARPF/iZE3OkCpmfsemCz9mLaqBhGPd3Qub2sQ=
|
||||
cloud.google.com/go/spanner v1.54.0/go.mod h1:wZvSQVBgngF0Gq86fKup6KIYmN2be7uOKjtK97X+bQU=
|
||||
cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
|
||||
cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
|
||||
cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=
|
||||
|
@ -721,7 +708,6 @@ cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeL
|
|||
cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
|
||||
cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=
|
||||
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
|
||||
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
|
||||
cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w=
|
||||
cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I=
|
||||
|
@ -988,7 +974,6 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC
|
|||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
||||
github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs=
|
||||
github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc=
|
||||
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||
|
@ -1061,7 +1046,6 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy
|
|||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g=
|
||||
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
|
||||
github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166 h1:jQ93fKqb/wRmK/KiHpa7Tk9rmHeKXhp4j+5Sg/tENiY=
|
||||
github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166/go.mod h1:c/gmvyN8lq6lYtHvrqqoXrg2xyN65N0mBmbikxFWXNE=
|
||||
|
@ -1101,7 +1085,6 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
|||
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/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk=
|
||||
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/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=
|
||||
|
@ -1113,8 +1096,6 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH
|
|||
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101 h1:7To3pQ+pZo0i3dsWEbinPNFs5gPSBOsJtx3wTT94VBY=
|
||||
github.com/cncf/xds/go v0.0.0-20231109132714-523115ebc101/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c h1:2zRrJWIt/f9c9HhNHAgrRgq0San5gRRUJTBXLkchal0=
|
||||
|
@ -1389,7 +1370,6 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.
|
|||
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
|
||||
github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI=
|
||||
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
|
||||
github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM=
|
||||
github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
|
||||
|
@ -1397,7 +1377,6 @@ github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0+
|
|||
github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
|
||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
|
@ -1707,7 +1686,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
|
|||
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 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
|
||||
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
|
||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
|
@ -1765,8 +1743,6 @@ github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYV
|
|||
github.com/google/go-containerregistry v0.14.0/go.mod h1:aiJ2fp/SXvkWgmYHioXnbMdlgB8eXiiYOY55gfN91Wk=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0 h1:rbs2sxHAPn2OtUj9JdR/Gij1YKGl0BTVD0augB+HEjE=
|
||||
github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJSZktIsTjb50eB72U2YZ9K0=
|
||||
github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
|
@ -1774,12 +1750,10 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
|||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible 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/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.2/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=
|
||||
|
@ -1912,8 +1886,6 @@ github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 h1:eje2KOX8S
|
|||
github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192/go.mod h1:3/4dzY4lR1Hzt9bBqMhBzG7lngZ0GKx/nL6G/ad62wE=
|
||||
github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg=
|
||||
github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4=
|
||||
github.com/hashicorp/go-gcp-common v0.8.0 h1:/2vGAbCU1v+BZ3YHXTCzTvxqma9WOJHYtADTfhZixLo=
|
||||
github.com/hashicorp/go-gcp-common v0.8.0/go.mod h1:Q7zYRy9ue9SuaEN2s9YLIQs4SoKHdoRmKRcImY3SLgs=
|
||||
github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
|
@ -1935,8 +1907,6 @@ github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1 h1:ZV26VJYcITBom0
|
|||
github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2 v2.0.7-1/go.mod h1:b99cDSA+OzcyRoBZroSf174/ss/e6gUuS45wue9ZQfc=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7 h1:E3eEWpkofgPNrYyYznfS1+drq4/jFcqHQVNcL7WhUCo=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 v2.0.7/go.mod h1:j5vefRoguQUG7iM4reS/hKIZssU1lZRqNPM5Wow6UnM=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.8 h1:16I8OqBEuxZIowwn3jiLvhlx+z+ia4dJc9stvz0yUBU=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2 v2.0.8/go.mod h1:6QUMo5BrXAtbzSuZilqmx0A4px2u6PeFK7vfp2WIzeM=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7 h1:KeG3QGrbxbr2qAqCJdf3NR4ijAYwdcWLTmwSbR0yusM=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2 v2.0.7/go.mod h1:rXxYzjjGw4HltEwxPp9zYSRIo6R+rBf1MSPk01bvodc=
|
||||
github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2 v2.0.7 h1:G25tZFw/LrAzJWxvS0/BFI7V1xAP/UsAIsgBwiE0mwo=
|
||||
|
@ -2068,8 +2038,6 @@ github.com/hashicorp/vault-plugin-auth-centrify v0.15.1 h1:6StAr5tltpySNgyUwWC8c
|
|||
github.com/hashicorp/vault-plugin-auth-centrify v0.15.1/go.mod h1:xXs4I5yLxbQ5VHcpvSxkRhShCTXd8Zyrni8qnFrfQ4Y=
|
||||
github.com/hashicorp/vault-plugin-auth-cf v0.15.0 h1:zIVGlYXCRBY/ElucWdFC9xF27d2QMGMQPm9wSezGREI=
|
||||
github.com/hashicorp/vault-plugin-auth-cf v0.15.0/go.mod h1:FEIjQkYmzno4MfU36MAjFUG9/JUWeMPxvBG5DRTMYVM=
|
||||
github.com/hashicorp/vault-plugin-auth-gcp v0.16.0 h1:DA/ZDLCrUsbHS/7Xqkkw7l2SgbQE9rWEHLLWYTGu8rw=
|
||||
github.com/hashicorp/vault-plugin-auth-gcp v0.16.0/go.mod h1:R0z/qdyxn0uq6hkKgux8KwenjV/n/CCaEz+qOF9GdPg=
|
||||
github.com/hashicorp/vault-plugin-auth-jwt v0.16.1 h1:QUGRRvO3x+4+/leav+K2I9BVeGJcSBjCjgNbsZXrSTA=
|
||||
github.com/hashicorp/vault-plugin-auth-jwt v0.16.1/go.mod h1:m5dbjs4Ept6CCHn+E6rRQzgwWBDX4nFcms6ycrBc/4c=
|
||||
github.com/hashicorp/vault-plugin-auth-kerberos v0.10.0 h1:YH2x9kIV0jKXk22tVkpydhmPeEgprC7IOfN8l0pjF6c=
|
||||
|
@ -2082,10 +2050,6 @@ github.com/hashicorp/vault-plugin-mock v0.16.1 h1:5QQvSUHxDjEEbrd2REOeacqyJnCLPD
|
|||
github.com/hashicorp/vault-plugin-mock v0.16.1/go.mod h1:83G4JKlOwUtxVourn5euQfze3ZWyXcUiLj2wqrKSDIM=
|
||||
github.com/hashicorp/vault-plugin-secrets-ad v0.16.0 h1:6RCpd2PbBvmi5xmxXhggE0Xv+/Gag896/NNZeMKH+8A=
|
||||
github.com/hashicorp/vault-plugin-secrets-ad v0.16.0/go.mod h1:6IeXly3xi+dVodzFSx6aVZjdhd3syboPyhxr1/WMcyo=
|
||||
github.com/hashicorp/vault-plugin-secrets-gcp v0.16.0 h1:5ozLtt38Bw/DLt37dbccT8j56A+2T7CWFfYecKleGl4=
|
||||
github.com/hashicorp/vault-plugin-secrets-gcp v0.16.0/go.mod h1:Ax9/ALmpzyjU8mcqHVYR9lwjcyazdmimrShDYeK9CHc=
|
||||
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.15.0 h1:CueteKXEuO52qGu1nUaDc/euSTSfQD9MONkXuvWdZQw=
|
||||
github.com/hashicorp/vault-plugin-secrets-gcpkms v0.15.0/go.mod h1:a0Z2DVGd2SPPwLb8edXeHyer3CXei/Y0cb7EFkiFMfA=
|
||||
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.5.0 h1:g0W1ybHjO945jDtuDEFcqTINyW/s06wxZarE/7aLumc=
|
||||
github.com/hashicorp/vault-plugin-secrets-kubernetes v0.5.0/go.mod h1:2wobeIypBESGQYmhv12vuAorCvfETHpBoMyrb+6QTmQ=
|
||||
github.com/hashicorp/vault-plugin-secrets-kv v0.15.0 h1:S2d1t4m4ilDNJRdMUzNUimvyu/+ll8huq5QncVgYz+s=
|
||||
|
@ -2197,8 +2161,6 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
|
|||
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2 h1:mex1izRBCD+7WjieGgRdy7e651vD/lvB1bD9vNE/3K4=
|
||||
github.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2/go.mod h1:xkfESuHriIekR+4RoV+fu91j/CfnYM29Zi2tMFw5iD4=
|
||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f h1:E87tDTVS5W65euzixn7clSzK66puSt1H4I5SC0EmHH4=
|
||||
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f/go.mod h1:3J2qVK16Lq8V+wfiL2lPeDZ7UWMxk5LemerHa1p6N00=
|
||||
github.com/jefferai/jsonx v1.0.0 h1:Xoz0ZbmkpBvED5W9W1B5B/zc3Oiq7oXqiW7iRV3B6EI=
|
||||
|
@ -2986,8 +2948,6 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2
|
|||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.45.0/go.mod h1:vsh3ySueQCiKPxFLvjWC4Z135gIa34TQ/NSqkDTZYUM=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c=
|
||||
|
@ -3697,7 +3657,6 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
|
||||
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
|
||||
|
@ -3709,7 +3668,6 @@ gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
|
|||
gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo=
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.5.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=
|
||||
|
@ -3790,7 +3748,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
|
|||
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-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
|
@ -3976,7 +3933,6 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
|
|||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
|
||||
|
|
|
@ -8,14 +8,11 @@ import (
|
|||
|
||||
credCentrify "github.com/hashicorp/vault-plugin-auth-centrify"
|
||||
credCF "github.com/hashicorp/vault-plugin-auth-cf"
|
||||
credGcp "github.com/hashicorp/vault-plugin-auth-gcp/plugin"
|
||||
credJWT "github.com/hashicorp/vault-plugin-auth-jwt"
|
||||
credKerb "github.com/hashicorp/vault-plugin-auth-kerberos"
|
||||
credKube "github.com/hashicorp/vault-plugin-auth-kubernetes"
|
||||
credOCI "github.com/hashicorp/vault-plugin-auth-oci"
|
||||
logicalAd "github.com/hashicorp/vault-plugin-secrets-ad/plugin"
|
||||
logicalGcp "github.com/hashicorp/vault-plugin-secrets-gcp/plugin"
|
||||
logicalGcpKms "github.com/hashicorp/vault-plugin-secrets-gcpkms"
|
||||
logicalKube "github.com/hashicorp/vault-plugin-secrets-kubernetes"
|
||||
logicalKv "github.com/hashicorp/vault-plugin-secrets-kv"
|
||||
logicalLDAP "github.com/hashicorp/vault-plugin-secrets-openldap"
|
||||
|
@ -90,7 +87,6 @@ func newRegistry() *registry {
|
|||
"centrify": {Factory: credCentrify.Factory},
|
||||
"cert": {Factory: credCert.Factory},
|
||||
"cf": {Factory: credCF.Factory},
|
||||
"gcp": {Factory: credGcp.Factory},
|
||||
"github": {Factory: credGitHub.Factory},
|
||||
"jwt": {Factory: credJWT.Factory},
|
||||
"kerberos": {Factory: credKerb.Factory},
|
||||
|
@ -128,8 +124,6 @@ func newRegistry() *registry {
|
|||
DeprecationStatus: consts.Removed,
|
||||
},
|
||||
"consul": {Factory: logicalConsul.Factory},
|
||||
"gcp": {Factory: logicalGcp.Factory},
|
||||
"gcpkms": {Factory: logicalGcpKms.Factory},
|
||||
"kubernetes": {Factory: logicalKube.Factory},
|
||||
"kv": {Factory: logicalKv.Factory},
|
||||
"mysql": {
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package fakegcsserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
"github.com/hashicorp/vault/sdk/helper/docker"
|
||||
"google.golang.org/api/iterator"
|
||||
"google.golang.org/api/option"
|
||||
)
|
||||
|
||||
// In principle we don't need docker for fake-gcs-server, we could run it in
|
||||
// memory instead. However I had an error trying to use it:
|
||||
// go: finding module for package google.golang.org/grpc/naming
|
||||
// github.com/hashicorp/vault/vault imports
|
||||
// google.golang.org/grpc/naming: module google.golang.org/grpc@latest found (v1.32.0), but does not contain package google.golang.org/grpc/naming
|
||||
// so it seemed easiest to go this route. Vault already has too many deps anyway.
|
||||
|
||||
func PrepareTestContainer(t *testing.T, version string) (func(), docker.ServiceConfig) {
|
||||
if version == "" {
|
||||
version = "latest"
|
||||
}
|
||||
runner, err := docker.NewServiceRunner(docker.RunOptions{
|
||||
ContainerName: "fake-gcs-server",
|
||||
ImageRepo: "docker.mirror.hashicorp.services/fsouza/fake-gcs-server",
|
||||
ImageTag: version,
|
||||
Cmd: []string{"-scheme", "http", "-public-host", "storage.gcs.127.0.0.1.nip.io:4443"},
|
||||
Ports: []string{"4443/tcp"},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Could not start docker fake-gcs-server: %s", err)
|
||||
}
|
||||
|
||||
svc, err := runner.StartService(context.Background(), connectGCS)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not start docker fake-gcs-server: %s", err)
|
||||
}
|
||||
|
||||
return svc.Cleanup, svc.Config
|
||||
}
|
||||
|
||||
func connectGCS(ctx context.Context, host string, port int) (docker.ServiceConfig, error) {
|
||||
u := url.URL{
|
||||
Scheme: "http",
|
||||
Host: fmt.Sprintf("%s:%d", host, port),
|
||||
Path: "storage/v1/b",
|
||||
}
|
||||
transCfg := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // ignore expired SSL certificates
|
||||
}
|
||||
httpClient := &http.Client{Transport: transCfg}
|
||||
client, err := storage.NewClient(context.TODO(), option.WithEndpoint(u.String()), option.WithHTTPClient(httpClient))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
it := client.Buckets(ctx, "test")
|
||||
for {
|
||||
_, err := it.Next()
|
||||
if err == iterator.Done {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return docker.NewServiceURL(u), nil
|
||||
}
|
|
@ -259,10 +259,6 @@ func (c *SharedConfig) Sanitized() map[string]interface{} {
|
|||
"dogstatsd_addr": c.Telemetry.DogStatsDAddr,
|
||||
"dogstatsd_tags": c.Telemetry.DogStatsDTags,
|
||||
"prometheus_retention_time": c.Telemetry.PrometheusRetentionTime,
|
||||
"stackdriver_project_id": c.Telemetry.StackdriverProjectID,
|
||||
"stackdriver_location": c.Telemetry.StackdriverLocation,
|
||||
"stackdriver_namespace": c.Telemetry.StackdriverNamespace,
|
||||
"stackdriver_debug_logs": c.Telemetry.StackdriverDebugLogs,
|
||||
"lease_metrics_epsilon": c.Telemetry.LeaseMetricsEpsilon,
|
||||
"num_lease_metrics_buckets": c.Telemetry.NumLeaseMetricsTimeBuckets,
|
||||
"add_lease_metrics_namespace_labels": c.Telemetry.LeaseMetricsNameSpaceLabels,
|
||||
|
|
|
@ -14,7 +14,6 @@ import (
|
|||
"github.com/hashicorp/go-hclog"
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
||||
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2"
|
||||
"github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2"
|
||||
"github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2"
|
||||
"github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
|
@ -172,9 +171,6 @@ func configureWrapper(configKMS *KMS, infoKeys *[]string, info *map[string]strin
|
|||
case wrapping.WrapperTypeAead:
|
||||
wrapper, kmsInfo, err = GetAEADKMSFunc(configKMS, opts...)
|
||||
|
||||
case wrapping.WrapperTypeGcpCkms:
|
||||
wrapper, kmsInfo, err = GetGCPCKMSKMSFunc(configKMS, opts...)
|
||||
|
||||
case wrapping.WrapperTypeOciKms:
|
||||
if keyId, ok := configKMS.Config["key_id"]; ok {
|
||||
opts = append(opts, wrapping.WithKeyId(keyId))
|
||||
|
@ -221,25 +217,6 @@ func GetAEADKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[st
|
|||
return wrapper, info, nil
|
||||
}
|
||||
|
||||
func GetGCPCKMSKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
||||
wrapper := gcpckms.NewWrapper()
|
||||
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithConfigMap(kms.Config))...)
|
||||
if err != nil {
|
||||
// If the error is any other than logical.KeyNotFoundError, return the error
|
||||
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
info := make(map[string]string)
|
||||
if wrapperInfo != nil {
|
||||
info["GCP KMS Project"] = wrapperInfo.Metadata["project"]
|
||||
info["GCP KMS Region"] = wrapperInfo.Metadata["region"]
|
||||
info["GCP KMS Key Ring"] = wrapperInfo.Metadata["key_ring"]
|
||||
info["GCP KMS Crypto Key"] = wrapperInfo.Metadata["crypto_key"]
|
||||
}
|
||||
return wrapper, info, nil
|
||||
}
|
||||
|
||||
func GetOCIKMSKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
||||
wrapper := ocikms.NewWrapper()
|
||||
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithConfigMap(kms.Config))...)
|
||||
|
|
|
@ -4,26 +4,21 @@
|
|||
package configutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
|
||||
monitoring "cloud.google.com/go/monitoring/apiv3"
|
||||
"github.com/armon/go-metrics"
|
||||
"github.com/armon/go-metrics/circonus"
|
||||
"github.com/armon/go-metrics/datadog"
|
||||
"github.com/armon/go-metrics/prometheus"
|
||||
stackdriver "github.com/google/go-metrics-stackdriver"
|
||||
stackdrivervault "github.com/google/go-metrics-stackdriver/vault"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/hcl"
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
"github.com/hashicorp/vault/helper/metricsutil"
|
||||
"github.com/mitchellh/cli"
|
||||
"google.golang.org/api/option"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -135,16 +130,6 @@ type Telemetry struct {
|
|||
PrometheusRetentionTime time.Duration `hcl:"-"`
|
||||
PrometheusRetentionTimeRaw interface{} `hcl:"prometheus_retention_time"`
|
||||
|
||||
// Stackdriver:
|
||||
// StackdriverProjectID is the project to publish stackdriver metrics to.
|
||||
StackdriverProjectID string `hcl:"stackdriver_project_id"`
|
||||
// StackdriverLocation is the GCP or AWS region of the monitored resource.
|
||||
StackdriverLocation string `hcl:"stackdriver_location"`
|
||||
// StackdriverNamespace is the namespace identifier, such as a cluster name.
|
||||
StackdriverNamespace string `hcl:"stackdriver_namespace"`
|
||||
// StackdriverDebugLogs will write additional stackdriver related debug logs to stderr.
|
||||
StackdriverDebugLogs bool `hcl:"stackdriver_debug_logs"`
|
||||
|
||||
// How often metrics for lease expiry will be aggregated
|
||||
LeaseMetricsEpsilon time.Duration
|
||||
LeaseMetricsEpsilonRaw interface{} `hcl:"lease_metrics_epsilon"`
|
||||
|
@ -362,23 +347,6 @@ func SetupTelemetry(opts *SetupTelemetryOpts) (*metrics.InmemSink, *metricsutil.
|
|||
fanout = append(fanout, sink)
|
||||
}
|
||||
|
||||
// Configure the stackdriver sink
|
||||
if opts.Config.StackdriverProjectID != "" {
|
||||
client, err := monitoring.NewMetricClient(context.Background(), option.WithUserAgent(opts.UserAgent))
|
||||
if err != nil {
|
||||
return nil, nil, false, fmt.Errorf("Failed to create stackdriver client: %v", err)
|
||||
}
|
||||
sink := stackdriver.NewSink(client, &stackdriver.Config{
|
||||
LabelExtractor: stackdrivervault.Extractor,
|
||||
Bucketer: stackdrivervault.Bucketer,
|
||||
ProjectID: opts.Config.StackdriverProjectID,
|
||||
Location: opts.Config.StackdriverLocation,
|
||||
Namespace: opts.Config.StackdriverNamespace,
|
||||
DebugLogs: opts.Config.StackdriverDebugLogs,
|
||||
})
|
||||
fanout = append(fanout, sink)
|
||||
}
|
||||
|
||||
// Initialize the global sink
|
||||
if len(fanout) > 1 {
|
||||
// Hostname enabled will create poor quality metrics name for prometheus
|
||||
|
|
|
@ -1,312 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package gcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
metrics "github.com/armon/go-metrics"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/vault/helper/useragent"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
"google.golang.org/api/iterator"
|
||||
"google.golang.org/api/option"
|
||||
)
|
||||
|
||||
// Verify Backend satisfies the correct interfaces
|
||||
var _ physical.Backend = (*Backend)(nil)
|
||||
|
||||
const (
|
||||
// envBucket is the name of the environment variable to search for the
|
||||
// storage bucket name.
|
||||
envBucket = "GOOGLE_STORAGE_BUCKET"
|
||||
|
||||
// envChunkSize is the environment variable to serach for the chunk size for
|
||||
// requests.
|
||||
envChunkSize = "GOOGLE_STORAGE_CHUNK_SIZE"
|
||||
|
||||
// envHAEnabled is the name of the environment variable to search for the
|
||||
// boolean indicating if HA is enabled.
|
||||
envHAEnabled = "GOOGLE_STORAGE_HA_ENABLED"
|
||||
|
||||
// defaultChunkSize is the number of bytes the writer will attempt to write in
|
||||
// a single request.
|
||||
defaultChunkSize = "8192"
|
||||
|
||||
// objectDelimiter is the string to use to delimit objects.
|
||||
objectDelimiter = "/"
|
||||
)
|
||||
|
||||
var (
|
||||
// metricDelete is the key for the metric for measuring a Delete call.
|
||||
metricDelete = []string{"gcs", "delete"}
|
||||
|
||||
// metricGet is the key for the metric for measuring a Get call.
|
||||
metricGet = []string{"gcs", "get"}
|
||||
|
||||
// metricList is the key for the metric for measuring a List call.
|
||||
metricList = []string{"gcs", "list"}
|
||||
|
||||
// metricPut is the key for the metric for measuring a Put call.
|
||||
metricPut = []string{"gcs", "put"}
|
||||
)
|
||||
|
||||
// Backend implements physical.Backend and describes the steps necessary to
|
||||
// persist data in Google Cloud Storage.
|
||||
type Backend struct {
|
||||
// bucket is the name of the bucket to use for data storage and retrieval.
|
||||
bucket string
|
||||
|
||||
// chunkSize is the chunk size to use for requests.
|
||||
chunkSize int
|
||||
|
||||
// client is the API client and permitPool is the allowed concurrent uses of
|
||||
// the client.
|
||||
client *storage.Client
|
||||
permitPool *physical.PermitPool
|
||||
|
||||
// haEnabled indicates if HA is enabled.
|
||||
haEnabled bool
|
||||
|
||||
// haClient is the API client. This is managed separately from the main client
|
||||
// because a flood of requests should not block refreshing the TTLs on the
|
||||
// lock.
|
||||
//
|
||||
// This value will be nil if haEnabled is false.
|
||||
haClient *storage.Client
|
||||
|
||||
// logger is an internal logger.
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// NewBackend constructs a Google Cloud Storage backend with the given
|
||||
// configuration. This uses the official Golang Cloud SDK and therefore supports
|
||||
// specifying credentials via envvars, credential files, etc. from environment
|
||||
// variables or a service account file
|
||||
func NewBackend(c map[string]string, logger log.Logger) (physical.Backend, error) {
|
||||
logger.Debug("configuring backend")
|
||||
|
||||
// Bucket name
|
||||
bucket := os.Getenv(envBucket)
|
||||
if bucket == "" {
|
||||
bucket = c["bucket"]
|
||||
}
|
||||
if bucket == "" {
|
||||
return nil, errors.New("missing bucket name")
|
||||
}
|
||||
|
||||
// Chunk size
|
||||
chunkSizeStr := os.Getenv(envChunkSize)
|
||||
if chunkSizeStr == "" {
|
||||
chunkSizeStr = c["chunk_size"]
|
||||
}
|
||||
if chunkSizeStr == "" {
|
||||
chunkSizeStr = defaultChunkSize
|
||||
}
|
||||
chunkSize, err := strconv.Atoi(chunkSizeStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse chunk_size: %w", err)
|
||||
}
|
||||
|
||||
// Values are specified as kb, but the API expects them as bytes.
|
||||
chunkSize = chunkSize * 1024
|
||||
|
||||
// HA configuration
|
||||
haClient := (*storage.Client)(nil)
|
||||
haEnabled := false
|
||||
haEnabledStr := os.Getenv(envHAEnabled)
|
||||
if haEnabledStr == "" {
|
||||
haEnabledStr = c["ha_enabled"]
|
||||
}
|
||||
if haEnabledStr != "" {
|
||||
var err error
|
||||
haEnabled, err = strconv.ParseBool(haEnabledStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse HA enabled: %w", err)
|
||||
}
|
||||
}
|
||||
if haEnabled {
|
||||
logger.Debug("creating client")
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
haClient, err = storage.NewClient(ctx, option.WithUserAgent(useragent.String()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create HA storage client: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Max parallel
|
||||
maxParallel, err := extractInt(c["max_parallel"])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse max_parallel: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("configuration",
|
||||
"bucket", bucket,
|
||||
"chunk_size", chunkSize,
|
||||
"ha_enabled", haEnabled,
|
||||
"max_parallel", maxParallel,
|
||||
)
|
||||
|
||||
logger.Debug("creating client")
|
||||
ctx := context.Background()
|
||||
client, err := storage.NewClient(ctx, option.WithUserAgent(useragent.String()))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create storage client: %w", err)
|
||||
}
|
||||
|
||||
return &Backend{
|
||||
bucket: bucket,
|
||||
chunkSize: chunkSize,
|
||||
client: client,
|
||||
permitPool: physical.NewPermitPool(maxParallel),
|
||||
|
||||
haEnabled: haEnabled,
|
||||
haClient: haClient,
|
||||
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Put is used to insert or update an entry
|
||||
func (b *Backend) Put(ctx context.Context, entry *physical.Entry) (retErr error) {
|
||||
defer metrics.MeasureSince(metricPut, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Insert
|
||||
w := b.client.Bucket(b.bucket).Object(entry.Key).NewWriter(ctx)
|
||||
w.ChunkSize = b.chunkSize
|
||||
md5Array := md5.Sum(entry.Value)
|
||||
w.MD5 = md5Array[:]
|
||||
defer func() {
|
||||
closeErr := w.Close()
|
||||
if closeErr != nil {
|
||||
retErr = multierror.Append(retErr, fmt.Errorf("error closing connection: %w", closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err := w.Write(entry.Value); err != nil {
|
||||
return fmt.Errorf("failed to put data: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get fetches an entry. If no entry exists, this function returns nil.
|
||||
func (b *Backend) Get(ctx context.Context, key string) (retEntry *physical.Entry, retErr error) {
|
||||
defer metrics.MeasureSince(metricGet, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Read
|
||||
r, err := b.client.Bucket(b.bucket).Object(key).NewReader(ctx)
|
||||
if err == storage.ErrObjectNotExist {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read value for %q: %w", key, err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
closeErr := r.Close()
|
||||
if closeErr != nil {
|
||||
retErr = multierror.Append(retErr, fmt.Errorf("error closing connection: %w", closeErr))
|
||||
}
|
||||
}()
|
||||
|
||||
value, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read value into a string: %w", err)
|
||||
}
|
||||
|
||||
return &physical.Entry{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Delete deletes an entry with the given key
|
||||
func (b *Backend) Delete(ctx context.Context, key string) error {
|
||||
defer metrics.MeasureSince(metricDelete, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Delete
|
||||
err := b.client.Bucket(b.bucket).Object(key).Delete(ctx)
|
||||
if err != nil && err != storage.ErrObjectNotExist {
|
||||
return fmt.Errorf("failed to delete key %q: %w", key, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// List is used to list all the keys under a given
|
||||
// prefix, up to the next prefix.
|
||||
func (b *Backend) List(ctx context.Context, prefix string) ([]string, error) {
|
||||
defer metrics.MeasureSince(metricList, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
iter := b.client.Bucket(b.bucket).Objects(ctx, &storage.Query{
|
||||
Prefix: prefix,
|
||||
Delimiter: objectDelimiter,
|
||||
Versions: false,
|
||||
})
|
||||
|
||||
keys := []string{}
|
||||
|
||||
for {
|
||||
objAttrs, err := iter.Next()
|
||||
if err == iterator.Done {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read object: %w", err)
|
||||
}
|
||||
|
||||
var path string
|
||||
if objAttrs.Prefix != "" {
|
||||
// "subdirectory"
|
||||
path = objAttrs.Prefix
|
||||
} else {
|
||||
// file
|
||||
path = objAttrs.Name
|
||||
}
|
||||
|
||||
// get relative file/dir just like "basename"
|
||||
key := strings.TrimPrefix(path, prefix)
|
||||
keys = append(keys, key)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// extractInt is a helper function that takes a string and converts that string
|
||||
// to an int, but accounts for the empty string.
|
||||
func extractInt(s string) (int, error) {
|
||||
if s == "" {
|
||||
return 0, nil
|
||||
}
|
||||
return strconv.Atoi(s)
|
||||
}
|
|
@ -1,416 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package gcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
metrics "github.com/armon/go-metrics"
|
||||
uuid "github.com/hashicorp/go-uuid"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
// Verify Backend satisfies the correct interfaces
|
||||
var (
|
||||
_ physical.HABackend = (*Backend)(nil)
|
||||
_ physical.Lock = (*Lock)(nil)
|
||||
)
|
||||
|
||||
const (
|
||||
// LockRenewInterval is the time to wait between lock renewals.
|
||||
LockRenewInterval = 5 * time.Second
|
||||
|
||||
// LockRetryInterval is the amount of time to wait if the lock fails before
|
||||
// trying again.
|
||||
LockRetryInterval = 5 * time.Second
|
||||
|
||||
// LockTTL is the default lock TTL.
|
||||
LockTTL = 15 * time.Second
|
||||
|
||||
// LockWatchRetryInterval is the amount of time to wait if a watch fails
|
||||
// before trying again.
|
||||
LockWatchRetryInterval = 5 * time.Second
|
||||
|
||||
// LockWatchRetryMax is the number of times to retry a failed watch before
|
||||
// signaling that leadership is lost.
|
||||
LockWatchRetryMax = 5
|
||||
)
|
||||
|
||||
var (
|
||||
// metricLockUnlock is the metric to register for a lock delete.
|
||||
metricLockUnlock = []string{"gcs", "lock", "unlock"}
|
||||
|
||||
// metricLockLock is the metric to register for a lock get.
|
||||
metricLockLock = []string{"gcs", "lock", "lock"}
|
||||
|
||||
// metricLockValue is the metric to register for a lock create/update.
|
||||
metricLockValue = []string{"gcs", "lock", "value"}
|
||||
)
|
||||
|
||||
// Lock is the HA lock.
|
||||
type Lock struct {
|
||||
// backend is the underlying physical backend.
|
||||
backend *Backend
|
||||
|
||||
// key is the name of the key. value is the value of the key.
|
||||
key, value string
|
||||
|
||||
// held is a boolean indicating if the lock is currently held.
|
||||
held bool
|
||||
|
||||
// identity is the internal identity of this key (unique to this server
|
||||
// instance).
|
||||
identity string
|
||||
|
||||
// lock is an internal lock
|
||||
lock sync.Mutex
|
||||
|
||||
// stopCh is the channel that stops all operations. It may be closed in the
|
||||
// event of a leader loss or graceful shutdown. stopped is a boolean
|
||||
// indicating if we are stopped - it exists to prevent double closing the
|
||||
// channel. stopLock is a mutex around the locks.
|
||||
stopCh chan struct{}
|
||||
stopped bool
|
||||
stopLock sync.Mutex
|
||||
|
||||
// Allow modifying the Lock durations for ease of unit testing.
|
||||
renewInterval time.Duration
|
||||
retryInterval time.Duration
|
||||
ttl time.Duration
|
||||
watchRetryInterval time.Duration
|
||||
watchRetryMax int
|
||||
}
|
||||
|
||||
// LockRecord is the struct that corresponds to a lock.
|
||||
type LockRecord struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Identity string `json:"identity"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
|
||||
// attrs are the internal object attributes. This is stored internally, for
|
||||
// internal consumption only.
|
||||
attrs *storage.ObjectAttrs
|
||||
}
|
||||
|
||||
// HAEnabled implements HABackend and indicates that this backend supports high
|
||||
// availability.
|
||||
func (b *Backend) HAEnabled() bool {
|
||||
return b.haEnabled
|
||||
}
|
||||
|
||||
// LockWith acquires a mutual exclusion based on the given key.
|
||||
func (b *Backend) LockWith(key, value string) (physical.Lock, error) {
|
||||
identity, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lock with: %w", err)
|
||||
}
|
||||
return &Lock{
|
||||
backend: b,
|
||||
key: key,
|
||||
value: value,
|
||||
identity: identity,
|
||||
stopped: true,
|
||||
|
||||
renewInterval: LockRenewInterval,
|
||||
retryInterval: LockRetryInterval,
|
||||
ttl: LockTTL,
|
||||
watchRetryInterval: LockWatchRetryInterval,
|
||||
watchRetryMax: LockWatchRetryMax,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Lock acquires the given lock. The stopCh is optional. If closed, it
|
||||
// interrupts the lock acquisition attempt. The returned channel should be
|
||||
// closed when leadership is lost.
|
||||
func (l *Lock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
|
||||
defer metrics.MeasureSince(metricLockLock, time.Now())
|
||||
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
if l.held {
|
||||
return nil, errors.New("lock already held")
|
||||
}
|
||||
|
||||
// Attempt to lock - this function blocks until a lock is acquired or an error
|
||||
// occurs.
|
||||
acquired, err := l.attemptLock(stopCh)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lock: %w", err)
|
||||
}
|
||||
if !acquired {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// We have the lock now
|
||||
l.held = true
|
||||
|
||||
// Build the locks
|
||||
l.stopLock.Lock()
|
||||
l.stopCh = make(chan struct{})
|
||||
l.stopped = false
|
||||
l.stopLock.Unlock()
|
||||
|
||||
// Periodically renew and watch the lock
|
||||
go l.renewLock()
|
||||
go l.watchLock()
|
||||
|
||||
return l.stopCh, nil
|
||||
}
|
||||
|
||||
// Unlock releases the lock.
|
||||
func (l *Lock) Unlock() error {
|
||||
defer metrics.MeasureSince(metricLockUnlock, time.Now())
|
||||
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
if !l.held {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop any existing locking or renewal attempts
|
||||
l.stopLock.Lock()
|
||||
if !l.stopped {
|
||||
l.stopped = true
|
||||
close(l.stopCh)
|
||||
}
|
||||
l.stopLock.Unlock()
|
||||
|
||||
// Read the record value before deleting. This needs to be a CAS operation or
|
||||
// else we might be deleting someone else's lock.
|
||||
ctx := context.Background()
|
||||
r, err := l.get(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read lock for deletion: %w", err)
|
||||
}
|
||||
if r != nil && r.Identity == l.identity {
|
||||
ctx := context.Background()
|
||||
conds := storage.Conditions{
|
||||
GenerationMatch: r.attrs.Generation,
|
||||
MetagenerationMatch: r.attrs.Metageneration,
|
||||
}
|
||||
|
||||
obj := l.backend.haClient.Bucket(l.backend.bucket).Object(l.key)
|
||||
if err := obj.If(conds).Delete(ctx); err != nil {
|
||||
// If the pre-condition failed, it means that someone else has already
|
||||
// acquired the lock and we don't want to delete it.
|
||||
if terr, ok := err.(*googleapi.Error); ok && terr.Code == 412 {
|
||||
l.backend.logger.Debug("unlock: preconditions failed (lock already taken by someone else?)")
|
||||
} else {
|
||||
return fmt.Errorf("failed to delete lock: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We are no longer holding the lock
|
||||
l.held = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the value of the lock and if it is held.
|
||||
func (l *Lock) Value() (bool, string, error) {
|
||||
defer metrics.MeasureSince(metricLockValue, time.Now())
|
||||
|
||||
r, err := l.get(context.Background())
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if r == nil {
|
||||
return false, "", err
|
||||
}
|
||||
return true, string(r.Value), nil
|
||||
}
|
||||
|
||||
// attemptLock attempts to acquire a lock. If the given channel is closed, the
|
||||
// acquisition attempt stops. This function returns when a lock is acquired or
|
||||
// an error occurs.
|
||||
func (l *Lock) attemptLock(stopCh <-chan struct{}) (bool, error) {
|
||||
ticker := time.NewTicker(l.retryInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
acquired, err := l.writeLock()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("attempt lock: %w", err)
|
||||
}
|
||||
if !acquired {
|
||||
continue
|
||||
}
|
||||
|
||||
return true, nil
|
||||
case <-stopCh:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renewLock renews the given lock until the channel is closed.
|
||||
func (l *Lock) renewLock() {
|
||||
ticker := time.NewTicker(l.renewInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
l.writeLock()
|
||||
case <-l.stopCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// watchLock checks whether the lock has changed in the table and closes the
|
||||
// leader channel accordingly. If an error occurs during the check, watchLock
|
||||
// will retry the operation and then close the leader channel if it can't
|
||||
// succeed after retries.
|
||||
func (l *Lock) watchLock() {
|
||||
retries := 0
|
||||
ticker := time.NewTicker(l.watchRetryInterval)
|
||||
|
||||
OUTER:
|
||||
for {
|
||||
// Check if the channel is already closed
|
||||
select {
|
||||
case <-l.stopCh:
|
||||
break OUTER
|
||||
default:
|
||||
}
|
||||
|
||||
// Check if we've exceeded retries
|
||||
if retries >= l.watchRetryMax-1 {
|
||||
break OUTER
|
||||
}
|
||||
|
||||
// Wait for the timer
|
||||
select {
|
||||
case <-ticker.C:
|
||||
case <-l.stopCh:
|
||||
break OUTER
|
||||
}
|
||||
|
||||
// Attempt to read the key
|
||||
r, err := l.get(context.Background())
|
||||
if err != nil {
|
||||
retries++
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify the identity is the same
|
||||
if r == nil || r.Identity != l.identity {
|
||||
break OUTER
|
||||
}
|
||||
}
|
||||
|
||||
l.stopLock.Lock()
|
||||
defer l.stopLock.Unlock()
|
||||
if !l.stopped {
|
||||
l.stopped = true
|
||||
close(l.stopCh)
|
||||
}
|
||||
}
|
||||
|
||||
// writeLock writes the given lock using the following algorithm:
|
||||
//
|
||||
// - lock does not exist
|
||||
// - write the lock
|
||||
//
|
||||
// - lock exists
|
||||
// - if key is empty or identity is the same or timestamp exceeds TTL
|
||||
// - update the lock to self
|
||||
func (l *Lock) writeLock() (bool, error) {
|
||||
// Create a transaction to read and the update (maybe)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// The operation may be retried, so we need to stop it if we lose leadership.
|
||||
go func() {
|
||||
select {
|
||||
case <-l.stopCh:
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
// Build up the list of conditions
|
||||
var conds storage.Conditions
|
||||
|
||||
// Read the record
|
||||
r, err := l.get(ctx)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("write lock: %w", err)
|
||||
}
|
||||
if r != nil {
|
||||
// If the key is empty or the identity is ours or the ttl expired, we can
|
||||
// write. Otherwise, return now because we cannot.
|
||||
if r.Key != "" && r.Identity != l.identity && time.Now().UTC().Sub(r.Timestamp) < l.ttl {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// CAS operation
|
||||
conds.GenerationMatch = r.attrs.Generation
|
||||
conds.MetagenerationMatch = r.attrs.Metageneration
|
||||
} else {
|
||||
// Ensure no one created while we were working
|
||||
conds.DoesNotExist = true
|
||||
}
|
||||
|
||||
// Update the lock to now
|
||||
lockData, err := json.Marshal(&LockRecord{
|
||||
Key: l.key,
|
||||
Value: l.value,
|
||||
Identity: l.identity,
|
||||
Timestamp: time.Now().UTC(),
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("write lock: failed to encode JSON: %w", err)
|
||||
}
|
||||
|
||||
// Write the object
|
||||
obj := l.backend.haClient.Bucket(l.backend.bucket).Object(l.key)
|
||||
w := obj.If(conds).NewWriter(ctx)
|
||||
w.ObjectAttrs.CacheControl = "no-cache; no-store; max-age=0"
|
||||
w.ObjectAttrs.Metadata = map[string]string{
|
||||
"lock": string(lockData),
|
||||
}
|
||||
if err := w.Close(); err != nil {
|
||||
// If the pre-condition failed, it means that we already have a lock.
|
||||
if terr, ok := err.(*googleapi.Error); ok && terr.Code == 412 {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// get retrieves the value for the lock.
|
||||
func (l *Lock) get(ctx context.Context) (*LockRecord, error) {
|
||||
// Read
|
||||
attrs, err := l.backend.haClient.Bucket(l.backend.bucket).Object(l.key).Attrs(ctx)
|
||||
if err == storage.ErrObjectNotExist {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read attrs for %q: %w", l.key, err)
|
||||
}
|
||||
|
||||
// If we got this far, we have attributes, meaning the lockfile exists.
|
||||
var r LockRecord
|
||||
r.attrs = attrs
|
||||
lockData := []byte(attrs.Metadata["lock"])
|
||||
if err := json.Unmarshal(lockData, &r); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode lock: %w", err)
|
||||
}
|
||||
return &r, nil
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package gcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
)
|
||||
|
||||
func TestHABackend(t *testing.T) {
|
||||
projectID := os.Getenv("GOOGLE_PROJECT_ID")
|
||||
if projectID == "" {
|
||||
t.Skip("GOOGLE_PROJECT_ID not set")
|
||||
}
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
|
||||
bucket := fmt.Sprintf("vault-gcs-testacc-%d", r)
|
||||
|
||||
ctx := context.Background()
|
||||
client, err := storage.NewClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testCleanup(t, client, bucket)
|
||||
defer testCleanup(t, client, bucket)
|
||||
|
||||
bh := client.Bucket(bucket)
|
||||
if err := bh.Create(context.Background(), projectID, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
logger := logging.NewVaultLogger(log.Trace)
|
||||
config := map[string]string{
|
||||
"bucket": bucket,
|
||||
"ha_enabled": "true",
|
||||
}
|
||||
|
||||
b, err := NewBackend(config, logger)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b2, err := NewBackend(config, logger)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
physical.ExerciseBackend(t, b)
|
||||
physical.ExerciseBackend_ListPrefix(t, b)
|
||||
physical.ExerciseHABackend(t, b.(physical.HABackend), b2.(physical.HABackend))
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package gcs
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/storage"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
func testCleanup(t testing.TB, client *storage.Client, bucket string) {
|
||||
t.Helper()
|
||||
|
||||
ctx := context.Background()
|
||||
if err := client.Bucket(bucket).Delete(ctx); err != nil {
|
||||
if terr, ok := err.(*googleapi.Error); !ok || terr.Code != 404 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackend(t *testing.T) {
|
||||
projectID := os.Getenv("GOOGLE_PROJECT_ID")
|
||||
if projectID == "" {
|
||||
t.Skip("GOOGLE_PROJECT_ID not set")
|
||||
}
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
|
||||
bucket := fmt.Sprintf("vault-gcs-testacc-%d", r)
|
||||
|
||||
ctx := context.Background()
|
||||
client, err := storage.NewClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testCleanup(t, client, bucket)
|
||||
defer testCleanup(t, client, bucket)
|
||||
|
||||
b := client.Bucket(bucket)
|
||||
if err := b.Create(context.Background(), projectID, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
backend, err := NewBackend(map[string]string{
|
||||
"bucket": bucket,
|
||||
"ha_enabled": "false",
|
||||
}, logging.NewVaultLogger(log.Trace))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Verify chunkSize is set correctly on the Backend
|
||||
be := backend.(*Backend)
|
||||
expectedChunkSize, err := strconv.Atoi(defaultChunkSize)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to convert defaultChunkSize to int: %s", err)
|
||||
}
|
||||
expectedChunkSize = expectedChunkSize * 1024
|
||||
if be.chunkSize != expectedChunkSize {
|
||||
t.Fatalf("expected chunkSize to be %d. got=%d", expectedChunkSize, be.chunkSize)
|
||||
}
|
||||
|
||||
physical.ExerciseBackend(t, backend)
|
||||
physical.ExerciseBackend_ListPrefix(t, backend)
|
||||
}
|
|
@ -1,377 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package spanner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/spanner"
|
||||
metrics "github.com/armon/go-metrics"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-secure-stdlib/strutil"
|
||||
"github.com/hashicorp/vault/helper/useragent"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/api/iterator"
|
||||
"google.golang.org/api/option"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
// Verify Backend satisfies the correct interfaces
|
||||
var (
|
||||
_ physical.Backend = (*Backend)(nil)
|
||||
_ physical.Transactional = (*Backend)(nil)
|
||||
)
|
||||
|
||||
const (
|
||||
// envDatabase is the name of the environment variable to search for the
|
||||
// database name.
|
||||
envDatabase = "GOOGLE_SPANNER_DATABASE"
|
||||
|
||||
// envHAEnabled is the name of the environment variable to search for the
|
||||
// boolean indicating if HA is enabled.
|
||||
envHAEnabled = "GOOGLE_SPANNER_HA_ENABLED"
|
||||
|
||||
// envHATable is the name of the environment variable to search for the table
|
||||
// name to use for HA.
|
||||
envHATable = "GOOGLE_SPANNER_HA_TABLE"
|
||||
|
||||
// envTable is the name of the environment variable to search for the table
|
||||
// name.
|
||||
envTable = "GOOGLE_SPANNER_TABLE"
|
||||
|
||||
// defaultTable is the default table name if none is specified.
|
||||
defaultTable = "Vault"
|
||||
|
||||
// defaultHASuffix is the default suffix to apply to the table name if no
|
||||
// HA table is provided.
|
||||
defaultHASuffix = "HA"
|
||||
)
|
||||
|
||||
var (
|
||||
// metricDelete is the key for the metric for measuring a Delete call.
|
||||
metricDelete = []string{"spanner", "delete"}
|
||||
|
||||
// metricGet is the key for the metric for measuring a Get call.
|
||||
metricGet = []string{"spanner", "get"}
|
||||
|
||||
// metricList is the key for the metric for measuring a List call.
|
||||
metricList = []string{"spanner", "list"}
|
||||
|
||||
// metricPut is the key for the metric for measuring a Put call.
|
||||
metricPut = []string{"spanner", "put"}
|
||||
|
||||
// metricTxn is the key for the metric for measuring a Transaction call.
|
||||
metricTxn = []string{"spanner", "txn"}
|
||||
)
|
||||
|
||||
// Backend implements physical.Backend and describes the steps necessary to
|
||||
// persist data using Google Cloud Spanner.
|
||||
type Backend struct {
|
||||
// database is the name of the database to use for data storage and retrieval.
|
||||
// This is supplied as part of user configuration.
|
||||
database string
|
||||
|
||||
// table is the name of the table in the database.
|
||||
table string
|
||||
|
||||
// client is the API client and permitPool is the allowed concurrent uses of
|
||||
// the client.
|
||||
client *spanner.Client
|
||||
permitPool *physical.PermitPool
|
||||
|
||||
// haTable is the name of the table to use for HA in the database.
|
||||
haTable string
|
||||
|
||||
// haEnabled indicates if high availability is enabled. Default: true.
|
||||
haEnabled bool
|
||||
|
||||
// haClient is the API client. This is managed separately from the main client
|
||||
// because a flood of requests should not block refreshing the TTLs on the
|
||||
// lock.
|
||||
//
|
||||
// This value will be nil if haEnabled is false.
|
||||
haClient *spanner.Client
|
||||
|
||||
// logger is the internal logger.
|
||||
logger log.Logger
|
||||
}
|
||||
|
||||
// NewBackend creates a new Google Spanner storage backend with the given
|
||||
// configuration. This uses the official Golang Cloud SDK and therefore supports
|
||||
// specifying credentials via envvars, credential files, etc.
|
||||
func NewBackend(c map[string]string, logger log.Logger) (physical.Backend, error) {
|
||||
logger.Debug("configuring backend")
|
||||
|
||||
// Database name
|
||||
database := os.Getenv(envDatabase)
|
||||
if database == "" {
|
||||
database = c["database"]
|
||||
}
|
||||
if database == "" {
|
||||
return nil, errors.New("missing database name")
|
||||
}
|
||||
|
||||
// Table name
|
||||
table := os.Getenv(envTable)
|
||||
if table == "" {
|
||||
table = c["table"]
|
||||
}
|
||||
if table == "" {
|
||||
table = defaultTable
|
||||
}
|
||||
|
||||
// HA table name
|
||||
haTable := os.Getenv(envHATable)
|
||||
if haTable == "" {
|
||||
haTable = c["ha_table"]
|
||||
}
|
||||
if haTable == "" {
|
||||
haTable = table + defaultHASuffix
|
||||
}
|
||||
|
||||
// HA configuration
|
||||
haClient := (*spanner.Client)(nil)
|
||||
haEnabled := false
|
||||
haEnabledStr := os.Getenv(envHAEnabled)
|
||||
if haEnabledStr == "" {
|
||||
haEnabledStr = c["ha_enabled"]
|
||||
}
|
||||
if haEnabledStr != "" {
|
||||
var err error
|
||||
haEnabled, err = strconv.ParseBool(haEnabledStr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse HA enabled: %w", err)
|
||||
}
|
||||
}
|
||||
if haEnabled {
|
||||
logger.Debug("creating HA client")
|
||||
var err error
|
||||
ctx := context.Background()
|
||||
haClient, err = spanner.NewClient(ctx, database,
|
||||
option.WithUserAgent(useragent.String()),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create HA client: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Max parallel
|
||||
maxParallel, err := extractInt(c["max_parallel"])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse max_parallel: %w", err)
|
||||
}
|
||||
|
||||
logger.Debug("configuration",
|
||||
"database", database,
|
||||
"table", table,
|
||||
"haEnabled", haEnabled,
|
||||
"haTable", haTable,
|
||||
"maxParallel", maxParallel,
|
||||
)
|
||||
|
||||
logger.Debug("creating client")
|
||||
ctx := context.Background()
|
||||
client, err := spanner.NewClient(ctx, database,
|
||||
option.WithUserAgent(useragent.String()),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create spanner client: %w", err)
|
||||
}
|
||||
|
||||
return &Backend{
|
||||
database: database,
|
||||
table: table,
|
||||
client: client,
|
||||
permitPool: physical.NewPermitPool(maxParallel),
|
||||
|
||||
haEnabled: haEnabled,
|
||||
haTable: haTable,
|
||||
haClient: haClient,
|
||||
|
||||
logger: logger,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Put creates or updates an entry.
|
||||
func (b *Backend) Put(ctx context.Context, entry *physical.Entry) error {
|
||||
defer metrics.MeasureSince(metricPut, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Insert
|
||||
m := spanner.InsertOrUpdateMap(b.table, map[string]interface{}{
|
||||
"Key": entry.Key,
|
||||
"Value": entry.Value,
|
||||
})
|
||||
if _, err := b.client.Apply(ctx, []*spanner.Mutation{m}); err != nil {
|
||||
return fmt.Errorf("failed to put data: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get fetches an entry. If there is no entry, this function returns nil.
|
||||
func (b *Backend) Get(ctx context.Context, key string) (*physical.Entry, error) {
|
||||
defer metrics.MeasureSince(metricGet, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Read
|
||||
row, err := b.client.Single().ReadRow(ctx, b.table, spanner.Key{key}, []string{"Value"})
|
||||
if spanner.ErrCode(err) == codes.NotFound {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read value for %q: %w", key, err)
|
||||
}
|
||||
|
||||
var value []byte
|
||||
if err := row.Column(0, &value); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode value into bytes: %w", err)
|
||||
}
|
||||
|
||||
return &physical.Entry{
|
||||
Key: key,
|
||||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Delete deletes an entry with the given key.
|
||||
func (b *Backend) Delete(ctx context.Context, key string) error {
|
||||
defer metrics.MeasureSince(metricDelete, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Delete
|
||||
m := spanner.Delete(b.table, spanner.Key{key})
|
||||
if _, err := b.client.Apply(ctx, []*spanner.Mutation{m}); err != nil {
|
||||
return fmt.Errorf("failed to delete key: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List enumerates all keys with the given prefix.
|
||||
func (b *Backend) List(ctx context.Context, prefix string) ([]string, error) {
|
||||
defer metrics.MeasureSince(metricList, time.Now())
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Sanitize
|
||||
safeTable := sanitizeTable(b.table)
|
||||
|
||||
// List
|
||||
iter := b.client.Single().Query(ctx, spanner.Statement{
|
||||
SQL: "SELECT Key FROM " + safeTable + " WHERE STARTS_WITH(Key, @prefix)",
|
||||
Params: map[string]interface{}{
|
||||
"prefix": prefix,
|
||||
},
|
||||
})
|
||||
defer iter.Stop()
|
||||
|
||||
var keys []string
|
||||
|
||||
for {
|
||||
row, err := iter.Next()
|
||||
if err == iterator.Done {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read row: %w", err)
|
||||
}
|
||||
|
||||
var key string
|
||||
if err := row.Column(0, &key); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode key into string: %w", err)
|
||||
}
|
||||
|
||||
// The results will include the full prefix (folder) and any deeply-nested
|
||||
// prefixes (subfolders). Vault expects only the top-most things to be
|
||||
// included.
|
||||
key = strings.TrimPrefix(key, prefix)
|
||||
if i := strings.Index(key, "/"); i == -1 {
|
||||
// Add objects only from the current 'folder'
|
||||
keys = append(keys, key)
|
||||
} else {
|
||||
// Add truncated 'folder' paths
|
||||
keys = strutil.AppendIfMissing(keys, string(key[:i+1]))
|
||||
}
|
||||
}
|
||||
|
||||
// Sort because the resulting order is not predictable
|
||||
sort.Strings(keys)
|
||||
|
||||
return keys, nil
|
||||
}
|
||||
|
||||
// Transaction runs multiple entries via a single transaction.
|
||||
func (b *Backend) Transaction(ctx context.Context, txns []*physical.TxnEntry) error {
|
||||
defer metrics.MeasureSince(metricTxn, time.Now())
|
||||
|
||||
// Quit early if we can
|
||||
if len(txns) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build all the ops before taking out the pool
|
||||
ms := make([]*spanner.Mutation, len(txns))
|
||||
for i, tx := range txns {
|
||||
op, key, value := tx.Operation, tx.Entry.Key, tx.Entry.Value
|
||||
|
||||
switch op {
|
||||
case physical.DeleteOperation:
|
||||
ms[i] = spanner.Delete(b.table, spanner.Key{key})
|
||||
case physical.PutOperation:
|
||||
ms[i] = spanner.InsertOrUpdateMap(b.table, map[string]interface{}{
|
||||
"Key": key,
|
||||
"Value": value,
|
||||
})
|
||||
default:
|
||||
return fmt.Errorf("unsupported transaction operation: %q", op)
|
||||
}
|
||||
}
|
||||
|
||||
// Pooling
|
||||
b.permitPool.Acquire()
|
||||
defer b.permitPool.Release()
|
||||
|
||||
// Transactivate!
|
||||
if _, err := b.client.Apply(ctx, ms); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractInt is a helper function that takes a string and converts that string
|
||||
// to an int, but accounts for the empty string.
|
||||
func extractInt(s string) (int, error) {
|
||||
if s == "" {
|
||||
return 0, nil
|
||||
}
|
||||
return strconv.Atoi(s)
|
||||
}
|
||||
|
||||
// sanitizeTable attempts to sanitize the table name.
|
||||
func sanitizeTable(s string) string {
|
||||
end := strings.IndexRune(s, 0)
|
||||
if end > -1 {
|
||||
s = s[:end]
|
||||
}
|
||||
return strings.ReplaceAll(s, `"`, `""`)
|
||||
}
|
|
@ -1,410 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package spanner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"cloud.google.com/go/spanner"
|
||||
metrics "github.com/armon/go-metrics"
|
||||
uuid "github.com/hashicorp/go-uuid"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
"github.com/pkg/errors"
|
||||
"google.golang.org/grpc/codes"
|
||||
)
|
||||
|
||||
// Verify Backend satisfies the correct interfaces
|
||||
var (
|
||||
_ physical.HABackend = (*Backend)(nil)
|
||||
_ physical.Lock = (*Lock)(nil)
|
||||
)
|
||||
|
||||
const (
|
||||
// LockRenewInterval is the time to wait between lock renewals.
|
||||
LockRenewInterval = 5 * time.Second
|
||||
|
||||
// LockRetryInterval is the amount of time to wait if the lock fails before
|
||||
// trying again.
|
||||
LockRetryInterval = 5 * time.Second
|
||||
|
||||
// LockTTL is the default lock TTL.
|
||||
LockTTL = 15 * time.Second
|
||||
|
||||
// LockWatchRetryInterval is the amount of time to wait if a watch fails
|
||||
// before trying again.
|
||||
LockWatchRetryInterval = 5 * time.Second
|
||||
|
||||
// LockWatchRetryMax is the number of times to retry a failed watch before
|
||||
// signaling that leadership is lost.
|
||||
LockWatchRetryMax = 5
|
||||
)
|
||||
|
||||
var (
|
||||
// metricLockUnlock is the metric to register for a lock delete.
|
||||
metricLockUnlock = []string{"spanner", "lock", "unlock"}
|
||||
|
||||
// metricLockGet is the metric to register for a lock get.
|
||||
metricLockLock = []string{"spanner", "lock", "lock"}
|
||||
|
||||
// metricLockValue is the metric to register for a lock create/update.
|
||||
metricLockValue = []string{"spanner", "lock", "value"}
|
||||
)
|
||||
|
||||
// Lock is the HA lock.
|
||||
type Lock struct {
|
||||
// backend is the underlying physical backend.
|
||||
backend *Backend
|
||||
|
||||
// key is the name of the key. value is the value of the key.
|
||||
key, value string
|
||||
|
||||
// held is a boolean indicating if the lock is currently held.
|
||||
held bool
|
||||
|
||||
// identity is the internal identity of this key (unique to this server
|
||||
// instance).
|
||||
identity string
|
||||
|
||||
// lock is an internal lock
|
||||
lock sync.Mutex
|
||||
|
||||
// stopCh is the channel that stops all operations. It may be closed in the
|
||||
// event of a leader loss or graceful shutdown. stopped is a boolean
|
||||
// indicating if we are stopped - it exists to prevent double closing the
|
||||
// channel. stopLock is a mutex around the locks.
|
||||
stopCh chan struct{}
|
||||
stopped bool
|
||||
stopLock sync.Mutex
|
||||
|
||||
// Allow modifying the Lock durations for ease of unit testing.
|
||||
renewInterval time.Duration
|
||||
retryInterval time.Duration
|
||||
ttl time.Duration
|
||||
watchRetryInterval time.Duration
|
||||
watchRetryMax int
|
||||
}
|
||||
|
||||
// LockRecord is the struct that corresponds to a lock.
|
||||
type LockRecord struct {
|
||||
Key string
|
||||
Value string
|
||||
Identity string
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
// HAEnabled implements HABackend and indicates that this backend supports high
|
||||
// availability.
|
||||
func (b *Backend) HAEnabled() bool {
|
||||
return b.haEnabled
|
||||
}
|
||||
|
||||
// LockWith acquires a mutual exclusion based on the given key.
|
||||
func (b *Backend) LockWith(key, value string) (physical.Lock, error) {
|
||||
identity, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lock with: %w", err)
|
||||
}
|
||||
return &Lock{
|
||||
backend: b,
|
||||
key: key,
|
||||
value: value,
|
||||
identity: identity,
|
||||
stopped: true,
|
||||
|
||||
renewInterval: LockRenewInterval,
|
||||
retryInterval: LockRetryInterval,
|
||||
ttl: LockTTL,
|
||||
watchRetryInterval: LockWatchRetryInterval,
|
||||
watchRetryMax: LockWatchRetryMax,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Lock acquires the given lock. The stopCh is optional. If closed, it
|
||||
// interrupts the lock acquisition attempt. The returned channel should be
|
||||
// closed when leadership is lost.
|
||||
func (l *Lock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) {
|
||||
defer metrics.MeasureSince(metricLockLock, time.Now())
|
||||
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
if l.held {
|
||||
return nil, errors.New("lock already held")
|
||||
}
|
||||
|
||||
// Attempt to lock - this function blocks until a lock is acquired or an error
|
||||
// occurs.
|
||||
acquired, err := l.attemptLock(stopCh)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("lock: %w", err)
|
||||
}
|
||||
if !acquired {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// We have the lock now
|
||||
l.held = true
|
||||
|
||||
// Build the locks
|
||||
l.stopLock.Lock()
|
||||
l.stopCh = make(chan struct{})
|
||||
l.stopped = false
|
||||
l.stopLock.Unlock()
|
||||
|
||||
// Periodically renew and watch the lock
|
||||
go l.renewLock()
|
||||
go l.watchLock()
|
||||
|
||||
return l.stopCh, nil
|
||||
}
|
||||
|
||||
// Unlock releases the lock.
|
||||
func (l *Lock) Unlock() error {
|
||||
defer metrics.MeasureSince(metricLockUnlock, time.Now())
|
||||
|
||||
l.lock.Lock()
|
||||
defer l.lock.Unlock()
|
||||
if !l.held {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop any existing locking or renewal attempts
|
||||
l.stopLock.Lock()
|
||||
if !l.stopped {
|
||||
l.stopped = true
|
||||
close(l.stopCh)
|
||||
}
|
||||
l.stopLock.Unlock()
|
||||
|
||||
// Delete
|
||||
ctx := context.Background()
|
||||
if _, err := l.backend.haClient.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
|
||||
row, err := txn.ReadRow(ctx, l.backend.haTable, spanner.Key{l.key}, []string{"Identity"})
|
||||
if err != nil {
|
||||
if spanner.ErrCode(err) != codes.NotFound {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var r LockRecord
|
||||
if derr := row.ToStruct(&r); derr != nil {
|
||||
return fmt.Errorf("failed to decode to struct: %w", derr)
|
||||
}
|
||||
|
||||
// If the identity is different, that means that between the time that after
|
||||
// we stopped acquisition, the TTL expired and someone else grabbed the
|
||||
// lock. We do not want to delete a lock that is not our own.
|
||||
if r.Identity != l.identity {
|
||||
return nil
|
||||
}
|
||||
|
||||
return txn.BufferWrite([]*spanner.Mutation{
|
||||
spanner.Delete(l.backend.haTable, spanner.Key{l.key}),
|
||||
})
|
||||
}); err != nil {
|
||||
return fmt.Errorf("unlock: %w", err)
|
||||
}
|
||||
|
||||
// We are no longer holding the lock
|
||||
l.held = false
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the value of the lock and if it is held.
|
||||
func (l *Lock) Value() (bool, string, error) {
|
||||
defer metrics.MeasureSince(metricLockValue, time.Now())
|
||||
|
||||
r, err := l.get(context.Background())
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if r == nil {
|
||||
return false, "", err
|
||||
}
|
||||
return true, string(r.Value), nil
|
||||
}
|
||||
|
||||
// attemptLock attempts to acquire a lock. If the given channel is closed, the
|
||||
// acquisition attempt stops. This function returns when a lock is acquired or
|
||||
// an error occurs.
|
||||
func (l *Lock) attemptLock(stopCh <-chan struct{}) (bool, error) {
|
||||
ticker := time.NewTicker(l.retryInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
acquired, err := l.writeLock()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("attempt lock: %w", err)
|
||||
}
|
||||
if !acquired {
|
||||
continue
|
||||
}
|
||||
|
||||
return true, nil
|
||||
case <-stopCh:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// renewLock renews the given lock until the channel is closed.
|
||||
func (l *Lock) renewLock() {
|
||||
ticker := time.NewTicker(l.renewInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
l.writeLock()
|
||||
case <-l.stopCh:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// watchLock checks whether the lock has changed in the table and closes the
|
||||
// leader channel accordingly. If an error occurs during the check, watchLock
|
||||
// will retry the operation and then close the leader channel if it can't
|
||||
// succeed after retries.
|
||||
func (l *Lock) watchLock() {
|
||||
retries := 0
|
||||
ticker := time.NewTicker(l.watchRetryInterval)
|
||||
|
||||
OUTER:
|
||||
for {
|
||||
// Check if the channel is already closed
|
||||
select {
|
||||
case <-l.stopCh:
|
||||
break OUTER
|
||||
default:
|
||||
}
|
||||
|
||||
// Check if we've exceeded retries
|
||||
if retries >= l.watchRetryMax-1 {
|
||||
break OUTER
|
||||
}
|
||||
|
||||
// Wait for the timer
|
||||
select {
|
||||
case <-ticker.C:
|
||||
case <-l.stopCh:
|
||||
break OUTER
|
||||
}
|
||||
|
||||
// Attempt to read the key
|
||||
r, err := l.get(context.Background())
|
||||
if err != nil {
|
||||
retries++
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify the identity is the same
|
||||
if r == nil || r.Identity != l.identity {
|
||||
break OUTER
|
||||
}
|
||||
}
|
||||
|
||||
l.stopLock.Lock()
|
||||
defer l.stopLock.Unlock()
|
||||
if !l.stopped {
|
||||
l.stopped = true
|
||||
close(l.stopCh)
|
||||
}
|
||||
}
|
||||
|
||||
// writeLock writes the given lock using the following algorithm:
|
||||
//
|
||||
// - lock does not exist
|
||||
// - write the lock
|
||||
//
|
||||
// - lock exists
|
||||
// - if key is empty or identity is the same or timestamp exceeds TTL
|
||||
// - update the lock to self
|
||||
func (l *Lock) writeLock() (bool, error) {
|
||||
// Keep track of whether the lock was written
|
||||
lockWritten := false
|
||||
|
||||
// Create a transaction to read and the update (maybe)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// The transaction will be retried, and it could sit in a queue behind, say,
|
||||
// the delete operation. To stop the transaction, we close the context when
|
||||
// the associated stopCh is received.
|
||||
go func() {
|
||||
select {
|
||||
case <-l.stopCh:
|
||||
cancel()
|
||||
case <-ctx.Done():
|
||||
}
|
||||
}()
|
||||
|
||||
_, err := l.backend.haClient.ReadWriteTransaction(ctx, func(ctx context.Context, txn *spanner.ReadWriteTransaction) error {
|
||||
row, err := txn.ReadRow(ctx, l.backend.haTable, spanner.Key{l.key}, []string{"Key", "Identity", "Timestamp"})
|
||||
if err != nil && spanner.ErrCode(err) != codes.NotFound {
|
||||
return err
|
||||
}
|
||||
|
||||
// If there was a record, verify that the record is still trustable.
|
||||
if row != nil {
|
||||
var r LockRecord
|
||||
if derr := row.ToStruct(&r); derr != nil {
|
||||
return fmt.Errorf("failed to decode to struct: %w", derr)
|
||||
}
|
||||
|
||||
// If the key is empty or the identity is ours or the ttl expired, we can
|
||||
// write. Otherwise, return now because we cannot.
|
||||
if r.Key != "" && r.Identity != l.identity && time.Now().UTC().Sub(r.Timestamp) < l.ttl {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
m, err := spanner.InsertOrUpdateStruct(l.backend.haTable, &LockRecord{
|
||||
Key: l.key,
|
||||
Value: l.value,
|
||||
Identity: l.identity,
|
||||
Timestamp: time.Now().UTC(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate struct: %w", err)
|
||||
}
|
||||
if err := txn.BufferWrite([]*spanner.Mutation{m}); err != nil {
|
||||
return fmt.Errorf("failed to write: %w", err)
|
||||
}
|
||||
|
||||
// Mark that the lock was acquired
|
||||
lockWritten = true
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("write lock: %w", err)
|
||||
}
|
||||
|
||||
return lockWritten, nil
|
||||
}
|
||||
|
||||
// get retrieves the value for the lock.
|
||||
func (l *Lock) get(ctx context.Context) (*LockRecord, error) {
|
||||
// Read
|
||||
row, err := l.backend.haClient.Single().ReadRow(ctx, l.backend.haTable, spanner.Key{l.key}, []string{"Key", "Value", "Timestamp", "Identity"})
|
||||
if spanner.ErrCode(err) == codes.NotFound {
|
||||
return nil, nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read value for %q: %w", l.key, err)
|
||||
}
|
||||
|
||||
var r LockRecord
|
||||
if err := row.ToStruct(&r); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode lock: %w", err)
|
||||
}
|
||||
return &r, nil
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package spanner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"cloud.google.com/go/spanner"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
)
|
||||
|
||||
func TestHABackend(t *testing.T) {
|
||||
database := os.Getenv("GOOGLE_SPANNER_DATABASE")
|
||||
if database == "" {
|
||||
t.Skip("GOOGLE_SPANNER_DATABASE not set")
|
||||
}
|
||||
|
||||
table := os.Getenv("GOOGLE_SPANNER_TABLE")
|
||||
if table == "" {
|
||||
t.Skip("GOOGLE_SPANNER_TABLE not set")
|
||||
}
|
||||
|
||||
haTable := os.Getenv("GOOGLE_SPANNER_HA_TABLE")
|
||||
if haTable == "" {
|
||||
t.Skip("GOOGLE_SPANNER_HA_TABLE not set")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
client, err := spanner.NewClient(ctx, database)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testCleanup(t, client, table)
|
||||
defer testCleanup(t, client, table)
|
||||
testCleanup(t, client, haTable)
|
||||
defer testCleanup(t, client, haTable)
|
||||
|
||||
logger := logging.NewVaultLogger(log.Debug)
|
||||
config := map[string]string{
|
||||
"database": database,
|
||||
"table": table,
|
||||
"ha_table": haTable,
|
||||
"ha_enabled": "true",
|
||||
}
|
||||
|
||||
b, err := NewBackend(config, logger)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
b2, err := NewBackend(config, logger)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
physical.ExerciseHABackend(t, b.(physical.HABackend), b2.(physical.HABackend))
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package spanner
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"cloud.google.com/go/spanner"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/sdk/helper/logging"
|
||||
"github.com/hashicorp/vault/sdk/physical"
|
||||
)
|
||||
|
||||
func testCleanup(t testing.TB, client *spanner.Client, table string) {
|
||||
t.Helper()
|
||||
|
||||
// Delete all data in the table
|
||||
ctx := context.Background()
|
||||
m := spanner.Delete(table, spanner.AllKeys())
|
||||
if _, err := client.Apply(ctx, []*spanner.Mutation{m}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackend(t *testing.T) {
|
||||
database := os.Getenv("GOOGLE_SPANNER_DATABASE")
|
||||
if database == "" {
|
||||
t.Skip("GOOGLE_SPANNER_DATABASE not set")
|
||||
}
|
||||
|
||||
table := os.Getenv("GOOGLE_SPANNER_TABLE")
|
||||
if table == "" {
|
||||
t.Skip("GOOGLE_SPANNER_TABLE not set")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
client, err := spanner.NewClient(ctx, database)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testCleanup(t, client, table)
|
||||
defer testCleanup(t, client, table)
|
||||
|
||||
backend, err := NewBackend(map[string]string{
|
||||
"database": database,
|
||||
"table": table,
|
||||
"ha_enabled": "false",
|
||||
}, logging.NewVaultLogger(log.Debug))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
physical.ExerciseBackend(t, backend)
|
||||
physical.ExerciseBackend_ListPrefix(t, backend)
|
||||
physical.ExerciseTransactionalBackend(t, backend)
|
||||
}
|
|
@ -54,7 +54,6 @@ vault auth enable "approle"
|
|||
vault auth enable "centrify"
|
||||
vault auth enable "cert"
|
||||
vault auth enable "cf"
|
||||
vault auth enable "gcp"
|
||||
vault auth enable "github"
|
||||
vault auth enable "jwt"
|
||||
vault auth enable "kerberos"
|
||||
|
@ -68,8 +67,6 @@ vault auth enable "userpass"
|
|||
# Enable secrets plugins
|
||||
vault secrets enable "consul"
|
||||
vault secrets enable "database"
|
||||
vault secrets enable "gcp"
|
||||
vault secrets enable "gcpkms"
|
||||
vault secrets enable "kubernetes"
|
||||
vault secrets enable -path="kv-v1/" -version=1 "kv"
|
||||
vault secrets enable -path="kv-v2/" -version=2 "kv"
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import AuthConfig from './_base';
|
||||
|
||||
export default AuthConfig.extend();
|
|
@ -32,7 +32,6 @@ class DistributionData {
|
|||
}
|
||||
|
||||
const VALID_TYPES_BY_PROVIDER = {
|
||||
gcpckms: ['aes256-gcm96', 'rsa-2048', 'rsa-3072', 'rsa-4096', 'ecdsa-p256', 'ecdsa-p384', 'ecdsa-p521'],
|
||||
};
|
||||
export default class KeymgmtDistribute extends Component {
|
||||
@service store;
|
||||
|
@ -86,24 +85,6 @@ export default class KeymgmtDistribute extends Component {
|
|||
}
|
||||
|
||||
get operations() {
|
||||
const pt = this.providerType;
|
||||
if (pt === 'gcpckms') {
|
||||
const kt = this.keyModel?.type || '';
|
||||
switch (kt) {
|
||||
case 'aes256-gcm96':
|
||||
return ['encrypt', 'decrypt'];
|
||||
case 'rsa-2048':
|
||||
case 'rsa-3072':
|
||||
case 'rsa-4096':
|
||||
return ['decrypt', 'sign'];
|
||||
case 'ecdsa-p256':
|
||||
case 'ecdsa-p384':
|
||||
return ['sign'];
|
||||
default:
|
||||
return ['encrypt', 'decrypt', 'sign', 'verify', 'wrap', 'unwrap'];
|
||||
}
|
||||
}
|
||||
|
||||
return ['encrypt', 'decrypt', 'sign', 'verify', 'wrap', 'unwrap'];
|
||||
}
|
||||
|
||||
|
|
|
@ -18,13 +18,6 @@ const MOUNTABLE_AUTH_METHODS = [
|
|||
type: 'approle',
|
||||
category: 'generic',
|
||||
},
|
||||
{
|
||||
displayName: 'Google Cloud',
|
||||
value: 'gcp',
|
||||
type: 'gcp',
|
||||
category: 'cloud',
|
||||
glyph: 'gcp-color',
|
||||
},
|
||||
{
|
||||
displayName: 'GitHub',
|
||||
value: 'github',
|
||||
|
|
|
@ -45,18 +45,6 @@ const MOUNTABLE_SECRET_ENGINES = [
|
|||
type: 'database',
|
||||
category: 'infra',
|
||||
},
|
||||
{
|
||||
displayName: 'Google Cloud',
|
||||
type: 'gcp',
|
||||
category: 'cloud',
|
||||
glyph: 'gcp-color',
|
||||
},
|
||||
{
|
||||
displayName: 'Google Cloud KMS',
|
||||
type: 'gcpkms',
|
||||
category: 'cloud',
|
||||
glyph: 'gcp-color',
|
||||
},
|
||||
{
|
||||
displayName: 'KV',
|
||||
type: 'kv',
|
||||
|
|
|
@ -14,12 +14,6 @@ const TABS_FOR_SETTINGS = {
|
|||
routeParams: ['vault.cluster.settings.auth.configure.section', 'configuration'],
|
||||
},
|
||||
],
|
||||
gcp: [
|
||||
{
|
||||
label: 'Configuration',
|
||||
routeParams: ['vault.cluster.settings.auth.configure.section', 'configuration'],
|
||||
},
|
||||
],
|
||||
jwt: [
|
||||
{
|
||||
label: 'Configuration',
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) HashiCorp, Inc.
|
||||
* SPDX-License-Identifier: BUSL-1.1
|
||||
*/
|
||||
|
||||
import { attr } from '@ember-data/model';
|
||||
import { computed } from '@ember/object';
|
||||
import AuthConfig from '../auth-config';
|
||||
import { combineFieldGroups } from 'vault/utils/openapi-to-attrs';
|
||||
import fieldToAttrs from 'vault/utils/field-to-attrs';
|
||||
|
||||
export default AuthConfig.extend({
|
||||
useOpenAPI: true,
|
||||
// We have to leave this here because the backend doesn't support the file type yet.
|
||||
credentials: attr('string', {
|
||||
editType: 'file',
|
||||
}),
|
||||
|
||||
googleCertsEndpoint: attr('string'),
|
||||
|
||||
fieldGroups: computed('newFields', function () {
|
||||
let groups = [
|
||||
{ default: ['credentials'] },
|
||||
{
|
||||
'Google Cloud Options': ['googleCertsEndpoint'],
|
||||
},
|
||||
];
|
||||
if (this.newFields) {
|
||||
groups = combineFieldGroups(groups, this.newFields, []);
|
||||
}
|
||||
return fieldToAttrs(this, groups);
|
||||
}),
|
||||
});
|
|
@ -11,7 +11,6 @@ import lazyCapabilities, { apiPath } from 'vault/macros/lazy-capabilities';
|
|||
import { inject as service } from '@ember/service';
|
||||
|
||||
const CRED_PROPS = {
|
||||
gcpckms: ['service_account_file'],
|
||||
};
|
||||
|
||||
const OPTIONAL_CRED_PROPS = ['session_token', 'endpoint'];
|
||||
|
@ -53,7 +52,7 @@ export default class KeymgmtProviderModel extends Model {
|
|||
@attr('string', {
|
||||
label: 'Type',
|
||||
subText: 'Choose the provider type.',
|
||||
possibleValues: ['gcpckms'],
|
||||
possibleValues: [],
|
||||
noDefault: true,
|
||||
})
|
||||
provider;
|
||||
|
@ -72,12 +71,10 @@ export default class KeymgmtProviderModel extends Model {
|
|||
|
||||
get icon() {
|
||||
return {
|
||||
gcpckms: 'gcp-color',
|
||||
}[this.provider];
|
||||
}
|
||||
get typeName() {
|
||||
return {
|
||||
gcpckms: 'Google Cloud Key Management Service',
|
||||
}[this.provider];
|
||||
}
|
||||
get showFields() {
|
||||
|
|
|
@ -18,7 +18,6 @@ export default Route.extend(UnloadModelRoute, {
|
|||
modelType(backendType, section) {
|
||||
const MODELS = {
|
||||
'github-configuration': 'auth-config/github',
|
||||
'gcp-configuration': 'auth-config/gcp',
|
||||
'jwt-configuration': 'auth-config/jwt',
|
||||
'oidc-configuration': 'auth-config/oidc',
|
||||
'kubernetes-configuration': 'auth-config/kubernetes',
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<WizardSection
|
||||
@headerText="Google Cloud"
|
||||
@headerIcon="gcp-color"
|
||||
@docText="Docs: Google Cloud Secrets"
|
||||
@docPath="/docs/secrets/gcp/index.html"
|
||||
>
|
||||
<p>
|
||||
The Google Cloud Vault Secrets Engine dynamically generates Google Cloud service account keys and OAuth tokens based on
|
||||
IAM policies. This enables users to gain access to Google Cloud resources without needing to create or manage a dedicated
|
||||
service account.
|
||||
</p>
|
||||
</WizardSection>
|
|
@ -1,15 +0,0 @@
|
|||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<WizardSection
|
||||
@headerText="Google Cloud"
|
||||
@headerIcon="gcp-color"
|
||||
@docText="Docs: Google Cloud Authentication"
|
||||
@docPath="/docs/auth/gcp.html"
|
||||
>
|
||||
<p>
|
||||
The GCP Auth Method allows authentication against Vault using Google credentials.
|
||||
</p>
|
||||
</WizardSection>
|
|
@ -1,17 +0,0 @@
|
|||
{{!
|
||||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
~}}
|
||||
|
||||
<WizardSection
|
||||
@headerText="Google Cloud KMS"
|
||||
@headerIcon="gcp-color"
|
||||
@docText="Docs: Google Cloud Secrets"
|
||||
@docPath="/docs/secrets/gcpkms/index.html"
|
||||
>
|
||||
<p>
|
||||
The Google Cloud KMS Vault Secrets Engine provides encryption and key management via Google Cloud KMS. It supports
|
||||
management of keys, including creation, rotation, and revocation, as well as encrypting and decrypting data with managed
|
||||
keys. This enables management of KMS keys through Vault's policies and IAM system.
|
||||
</p>
|
||||
</WizardSection>
|
|
@ -18,7 +18,6 @@ export const localIconMap = {
|
|||
approle: 'cpu',
|
||||
cert: 'certificate',
|
||||
consul: null,
|
||||
gcpkms: 'gcp-color',
|
||||
kmip: 'unlock',
|
||||
kv: 'key-values',
|
||||
ldap: 'user',
|
||||
|
@ -129,8 +128,6 @@ export const structureIconMap = {
|
|||
'logo-bitbucket-monochrome': 'bitbucket',
|
||||
'logo-f5-color': 'f5-color',
|
||||
'logo-f5-monochrome': 'f5',
|
||||
'logo-gcp-color': 'gcp-color',
|
||||
'logo-gcp-monochrome': 'gcp',
|
||||
'logo-github-color': 'github-color',
|
||||
'logo-github-monochrome': 'github',
|
||||
'logo-gitlab-color': 'gitlab-color',
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><path d="M29.218 15.807h1.213l3.454-3.454.17-1.467a15.527 15.527 0 0 0-25.26 7.576 1.879 1.879 0 0 1 1.211-.073l6.91-1.14s.351-.581.533-.545a8.618 8.618 0 0 1 11.794-.897h-.025z" fill="#EA4335"/><path d="M38.806 18.462a15.564 15.564 0 0 0-4.69-7.564l-4.849 4.849a8.618 8.618 0 0 1 3.164 6.836v.86a4.315 4.315 0 0 1 0 8.631H23.8l-.861.873v5.176l.86.86h8.63a11.224 11.224 0 0 0 6.376-20.521z" fill="#4285F4"/><path d="M15.158 38.935h8.63v-6.91h-8.63a4.29 4.29 0 0 1-1.782-.387l-1.212.375-3.479 3.455-.303 1.212a11.164 11.164 0 0 0 6.776 2.255z" fill="#34A853"/><path d="M15.158 16.523a11.224 11.224 0 0 0-6.776 20.12l5.006-5.005a4.315 4.315 0 1 1 5.71-5.71l5.005-5.005a11.212 11.212 0 0 0-8.945-4.4z" fill="#FBBC05"/></g></svg>
|
Before Width: | Height: | Size: 821 B |
|
@ -1 +0,0 @@
|
|||
<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="nonzero"><path d="M29.218 15.807h1.213l3.454-3.454.17-1.467a15.527 15.527 0 0 0-25.26 7.576 1.879 1.879 0 0 1 1.211-.073l6.91-1.14s.351-.581.533-.545a8.618 8.618 0 0 1 11.794-.897h-.025z" fill="#EA4335"/><path d="M38.806 18.462a15.564 15.564 0 0 0-4.69-7.564l-4.849 4.849a8.618 8.618 0 0 1 3.164 6.836v.86a4.315 4.315 0 0 1 0 8.631H23.8l-.861.873v5.176l.86.86h8.63a11.224 11.224 0 0 0 6.376-20.521z" fill="#4285F4"/><path d="M15.158 38.935h8.63v-6.91h-8.63a4.29 4.29 0 0 1-1.782-.387l-1.212.375-3.479 3.455-.303 1.212a11.164 11.164 0 0 0 6.776 2.255z" fill="#34A853"/><path d="M15.158 16.523a11.224 11.224 0 0 0-6.776 20.12l5.006-5.005a4.315 4.315 0 1 1 5.71-5.71l5.005-5.005a11.212 11.212 0 0 0-8.945-4.4z" fill="#FBBC05"/></g></svg>
|
Before Width: | Height: | Size: 821 B |
Loading…
Reference in New Issue
Block a user