diff --git a/go.mod b/go.mod index 312d9897e..8a096d87f 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( golang.org/x/sync v0.3.0 golang.org/x/tools v0.12.0 gomodules.xyz/jsonpatch/v2 v2.3.0 - google.golang.org/api v0.136.0 + google.golang.org/api v0.138.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 @@ -72,7 +72,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-querystring v1.0.0 // indirect - github.com/google/s2a-go v0.1.4 // indirect + github.com/google/s2a-go v0.1.5 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect diff --git a/go.sum b/go.sum index 24dadb4d2..2a34717a0 100644 --- a/go.sum +++ b/go.sum @@ -217,8 +217,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.5 h1:8IYp3w9nysqv3JH+NJgXJzGbDHzLOTj43BmSkp+O7qg= +github.com/google/s2a-go v0.1.5/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -653,8 +653,8 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M 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.136.0 h1:e/6enzUE1s4tGPa6Q3ZYShKTtvRc+1Jq0rrafhppmOs= -google.golang.org/api v0.136.0/go.mod h1:XtJfF+V2zgUxelOn5Zs3kECtluMxneJG8ZxUTlLNTPA= +google.golang.org/api v0.138.0 h1:K/tVp05MxNVbHShRw9m7e9VJGdagNeTdMzqPH7AUqr0= +google.golang.org/api v0.138.0/go.mod h1:4xyob8CxC+0GChNBvEUAk8VBKNvYOTWM9T3v3UfRxuY= 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= diff --git a/vendor/github.com/google/s2a-go/internal/v2/s2av2.go b/vendor/github.com/google/s2a-go/internal/v2/s2av2.go index ff172883f..26fac02dc 100644 --- a/vendor/github.com/google/s2a-go/internal/v2/s2av2.go +++ b/vendor/github.com/google/s2a-go/internal/v2/s2av2.go @@ -33,6 +33,7 @@ import ( "github.com/google/s2a-go/internal/handshaker/service" "github.com/google/s2a-go/internal/tokenmanager" "github.com/google/s2a-go/internal/v2/tlsconfigstore" + "github.com/google/s2a-go/retry" "github.com/google/s2a-go/stream" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -44,7 +45,7 @@ import ( const ( s2aSecurityProtocol = "tls" - defaultS2ATimeout = 3 * time.Second + defaultS2ATimeout = 6 * time.Second ) // An environment variable, which sets the timeout enforced on the connection to the S2A service for handshake. @@ -131,7 +132,13 @@ func (c *s2av2TransportCreds) ClientHandshake(ctx context.Context, serverAuthori serverName := removeServerNamePort(serverAuthority) timeoutCtx, cancel := context.WithTimeout(ctx, GetS2ATimeout()) defer cancel() - s2AStream, err := createStream(timeoutCtx, c.s2av2Address, c.getS2AStream) + var s2AStream stream.S2AStream + var err error + retry.Run(timeoutCtx, + func() error { + s2AStream, err = createStream(timeoutCtx, c.s2av2Address, c.getS2AStream) + return err + }) if err != nil { grpclog.Infof("Failed to connect to S2Av2: %v", err) if c.fallbackClientHandshake != nil { @@ -152,31 +159,34 @@ func (c *s2av2TransportCreds) ClientHandshake(ctx context.Context, serverAuthori tokenManager = *c.tokenManager } - if c.serverName == "" { - config, err = tlsconfigstore.GetTLSConfigurationForClient(serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy) - if err != nil { - grpclog.Info("Failed to get client TLS config from S2Av2: %v", err) - if c.fallbackClientHandshake != nil { - return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) - } - return nil, nil, err - } - } else { - config, err = tlsconfigstore.GetTLSConfigurationForClient(c.serverName, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy) - if err != nil { - grpclog.Info("Failed to get client TLS config from S2Av2: %v", err) - if c.fallbackClientHandshake != nil { - return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) - } - return nil, nil, err + sn := serverName + if c.serverName != "" { + sn = c.serverName + } + retry.Run(timeoutCtx, + func() error { + config, err = tlsconfigstore.GetTLSConfigurationForClient(sn, s2AStream, tokenManager, c.localIdentity, c.verificationMode, c.serverAuthorizationPolicy) + return err + }) + if err != nil { + grpclog.Info("Failed to get client TLS config from S2Av2: %v", err) + if c.fallbackClientHandshake != nil { + return c.fallbackClientHandshake(ctx, serverAuthority, rawConn, err) } + return nil, nil, err } if grpclog.V(1) { grpclog.Infof("Got client TLS config from S2Av2.") } - creds := credentials.NewTLS(config) - conn, authInfo, err := creds.ClientHandshake(ctx, serverName, rawConn) + creds := credentials.NewTLS(config) + var conn net.Conn + var authInfo credentials.AuthInfo + retry.Run(timeoutCtx, + func() error { + conn, authInfo, err = creds.ClientHandshake(timeoutCtx, serverName, rawConn) + return err + }) if err != nil { grpclog.Infof("Failed to do client handshake using S2Av2: %v", err) if c.fallbackClientHandshake != nil { @@ -196,7 +206,13 @@ func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, crede } ctx, cancel := context.WithTimeout(context.Background(), GetS2ATimeout()) defer cancel() - s2AStream, err := createStream(ctx, c.s2av2Address, c.getS2AStream) + var s2AStream stream.S2AStream + var err error + retry.Run(ctx, + func() error { + s2AStream, err = createStream(ctx, c.s2av2Address, c.getS2AStream) + return err + }) if err != nil { grpclog.Infof("Failed to connect to S2Av2: %v", err) return nil, nil, err @@ -213,7 +229,12 @@ func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, crede tokenManager = *c.tokenManager } - config, err := tlsconfigstore.GetTLSConfigurationForServer(s2AStream, tokenManager, c.localIdentities, c.verificationMode) + var config *tls.Config + retry.Run(ctx, + func() error { + config, err = tlsconfigstore.GetTLSConfigurationForServer(s2AStream, tokenManager, c.localIdentities, c.verificationMode) + return err + }) if err != nil { grpclog.Infof("Failed to get server TLS config from S2Av2: %v", err) return nil, nil, err @@ -221,8 +242,20 @@ func (c *s2av2TransportCreds) ServerHandshake(rawConn net.Conn) (net.Conn, crede if grpclog.V(1) { grpclog.Infof("Got server TLS config from S2Av2.") } + creds := credentials.NewTLS(config) - return creds.ServerHandshake(rawConn) + var conn net.Conn + var authInfo credentials.AuthInfo + retry.Run(ctx, + func() error { + conn, authInfo, err = creds.ServerHandshake(rawConn) + return err + }) + if err != nil { + grpclog.Infof("Failed to do server handshake using S2Av2: %v", err) + return nil, nil, err + } + return conn, authInfo, err } // Info returns protocol info of s2av2TransportCreds. diff --git a/vendor/github.com/google/s2a-go/retry/retry.go b/vendor/github.com/google/s2a-go/retry/retry.go new file mode 100644 index 000000000..224915f4d --- /dev/null +++ b/vendor/github.com/google/s2a-go/retry/retry.go @@ -0,0 +1,144 @@ +/* + * + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package retry provides a retry helper for talking to S2A gRPC server. +// The implementation is modeled after +// https://github.com/googleapis/google-cloud-go/blob/main/compute/metadata/retry.go +package retry + +import ( + "context" + "math/rand" + "time" + + "google.golang.org/grpc/grpclog" +) + +const ( + maxRetryAttempts = 5 + maxRetryForLoops = 10 +) + +type defaultBackoff struct { + max time.Duration + mul float64 + cur time.Duration +} + +// Pause returns a duration, which is used as the backoff wait time +// before the next retry. +func (b *defaultBackoff) Pause() time.Duration { + d := time.Duration(1 + rand.Int63n(int64(b.cur))) + b.cur = time.Duration(float64(b.cur) * b.mul) + if b.cur > b.max { + b.cur = b.max + } + return d +} + +// Sleep will wait for the specified duration or return on context +// expiration. +func Sleep(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return ctx.Err() + case <-t.C: + return nil + } +} + +// NewRetryer creates an instance of S2ARetryer using the defaultBackoff +// implementation. +var NewRetryer = func() *S2ARetryer { + return &S2ARetryer{bo: &defaultBackoff{ + cur: 100 * time.Millisecond, + max: 30 * time.Second, + mul: 2, + }} +} + +type backoff interface { + Pause() time.Duration +} + +// S2ARetryer implements a retry helper for talking to S2A gRPC server. +type S2ARetryer struct { + bo backoff + attempts int +} + +// Attempts return the number of retries attempted. +func (r *S2ARetryer) Attempts() int { + return r.attempts +} + +// Retry returns a boolean indicating whether retry should be performed +// and the backoff duration. +func (r *S2ARetryer) Retry(err error) (time.Duration, bool) { + if err == nil { + return 0, false + } + if r.attempts >= maxRetryAttempts { + return 0, false + } + r.attempts++ + return r.bo.Pause(), true +} + +// Run uses S2ARetryer to execute the function passed in, until success or reaching +// max number of retry attempts. +func Run(ctx context.Context, f func() error) { + retryer := NewRetryer() + forLoopCnt := 0 + var err error + for { + err = f() + if bo, shouldRetry := retryer.Retry(err); shouldRetry { + if grpclog.V(1) { + grpclog.Infof("will attempt retry: %v", err) + } + if ctx.Err() != nil { + if grpclog.V(1) { + grpclog.Infof("exit retry loop due to context error: %v", ctx.Err()) + } + break + } + if sleepErr := Sleep(ctx, bo); sleepErr != nil { + if grpclog.V(1) { + grpclog.Infof("exit retry loop due to sleep error: %v", sleepErr) + } + break + } + // This shouldn't happen, just make sure we are not stuck in the for loops. + forLoopCnt++ + if forLoopCnt > maxRetryForLoops { + if grpclog.V(1) { + grpclog.Infof("exit the for loop after too many retries") + } + break + } + continue + } + if grpclog.V(1) { + grpclog.Infof("retry conditions not met, exit the loop") + } + break + } +} diff --git a/vendor/github.com/google/s2a-go/s2a.go b/vendor/github.com/google/s2a-go/s2a.go index 1c1349de4..d684c2c73 100644 --- a/vendor/github.com/google/s2a-go/s2a.go +++ b/vendor/github.com/google/s2a-go/s2a.go @@ -35,6 +35,7 @@ import ( "github.com/google/s2a-go/internal/handshaker/service" "github.com/google/s2a-go/internal/tokenmanager" "github.com/google/s2a-go/internal/v2" + "github.com/google/s2a-go/retry" "google.golang.org/grpc/credentials" "google.golang.org/grpc/grpclog" @@ -390,9 +391,15 @@ func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, net } timeoutCtx, cancel := context.WithTimeout(ctx, v2.GetS2ATimeout()) defer cancel() - s2aTLSConfig, err := factory.Build(timeoutCtx, &TLSClientConfigOptions{ - ServerName: serverName, - }) + + var s2aTLSConfig *tls.Config + retry.Run(timeoutCtx, + func() error { + s2aTLSConfig, err = factory.Build(timeoutCtx, &TLSClientConfigOptions{ + ServerName: serverName, + }) + return err + }) if err != nil { grpclog.Infof("error building S2A TLS config: %v", err) return fallback(err) @@ -401,7 +408,12 @@ func NewS2ADialTLSContextFunc(opts *ClientOptions) func(ctx context.Context, net s2aDialer := &tls.Dialer{ Config: s2aTLSConfig, } - c, err := s2aDialer.DialContext(ctx, network, addr) + var c net.Conn + retry.Run(timeoutCtx, + func() error { + c, err = s2aDialer.DialContext(timeoutCtx, network, addr) + return err + }) if err != nil { grpclog.Infof("error dialing with S2A to %s: %v", addr, err) return fallback(err) diff --git a/vendor/google.golang.org/api/container/v1beta1/container-api.json b/vendor/google.golang.org/api/container/v1beta1/container-api.json index 1a6ab47e6..2c2099a8c 100644 --- a/vendor/google.golang.org/api/container/v1beta1/container-api.json +++ b/vendor/google.golang.org/api/container/v1beta1/container-api.json @@ -2565,7 +2565,7 @@ } } }, - "revision": "20230724", + "revision": "20230802", "rootUrl": "https://container.googleapis.com/", "schemas": { "AcceleratorConfig": { @@ -2964,14 +2964,25 @@ "enum": [ "EVALUATION_MODE_UNSPECIFIED", "DISABLED", - "PROJECT_SINGLETON_POLICY_ENFORCE" + "PROJECT_SINGLETON_POLICY_ENFORCE", + "POLICY_BINDINGS", + "POLICY_BINDINGS_AND_PROJECT_SINGLETON_POLICY_ENFORCE" ], "enumDescriptions": [ "Default value", "Disable BinaryAuthorization", - "Enforce Kubernetes admission requests with BinaryAuthorization using the project's singleton policy. This is equivalent to setting the enabled boolean to true." + "Enforce Kubernetes admission requests with BinaryAuthorization using the project's singleton policy. This is equivalent to setting the enabled boolean to true.", + "Use Binary Authorization with the policies specified in policy_bindings.", + "Use Binary Authorization with the policies specified in policy_bindings, and also with the project's singleton policy in enforcement mode." ], "type": "string" + }, + "policyBindings": { + "description": "Optional. Binauthz policies that apply to this cluster.", + "items": { + "$ref": "PolicyBinding" + }, + "type": "array" } }, "type": "object" @@ -6191,6 +6202,17 @@ }, "type": "object" }, + "PolicyBinding": { + "description": "Binauthz policy that applies to this cluster.", + "id": "PolicyBinding", + "properties": { + "name": { + "description": "The relative resource name of the binauthz platform policy to audit. GKE platform policies have the following format: `projects/{project_number}/platforms/gke/policies/{policy_id}`.", + "type": "string" + } + }, + "type": "object" + }, "PrivateClusterConfig": { "description": "Configuration options for private clusters.", "id": "PrivateClusterConfig", diff --git a/vendor/google.golang.org/api/container/v1beta1/container-gen.go b/vendor/google.golang.org/api/container/v1beta1/container-gen.go index 18543ba4d..bed5691fa 100644 --- a/vendor/google.golang.org/api/container/v1beta1/container-gen.go +++ b/vendor/google.golang.org/api/container/v1beta1/container-gen.go @@ -969,8 +969,17 @@ type BinaryAuthorization struct { // "PROJECT_SINGLETON_POLICY_ENFORCE" - Enforce Kubernetes admission // requests with BinaryAuthorization using the project's singleton // policy. This is equivalent to setting the enabled boolean to true. + // "POLICY_BINDINGS" - Use Binary Authorization with the policies + // specified in policy_bindings. + // "POLICY_BINDINGS_AND_PROJECT_SINGLETON_POLICY_ENFORCE" - Use Binary + // Authorization with the policies specified in policy_bindings, and + // also with the project's singleton policy in enforcement mode. EvaluationMode string `json:"evaluationMode,omitempty"` + // PolicyBindings: Optional. Binauthz policies that apply to this + // cluster. + PolicyBindings []*PolicyBinding `json:"policyBindings,omitempty"` + // ForceSendFields is a list of field names (e.g. "Enabled") to // unconditionally include in API requests. By default, fields with // empty or default values are omitted from API requests. However, any @@ -6216,6 +6225,36 @@ func (s *PodSecurityPolicyConfig) MarshalJSON() ([]byte, error) { return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) } +// PolicyBinding: Binauthz policy that applies to this cluster. +type PolicyBinding struct { + // Name: The relative resource name of the binauthz platform policy to + // audit. GKE platform policies have the following format: + // `projects/{project_number}/platforms/gke/policies/{policy_id}`. + Name string `json:"name,omitempty"` + + // ForceSendFields is a list of field names (e.g. "Name") to + // unconditionally include in API requests. By default, fields with + // empty or default values are omitted from API requests. However, any + // non-pointer, non-interface field appearing in ForceSendFields will be + // sent to the server regardless of whether the field is empty or not. + // This may be used to include empty fields in Patch requests. + ForceSendFields []string `json:"-"` + + // NullFields is a list of field names (e.g. "Name") to include in API + // requests with the JSON null value. By default, fields with empty + // values are omitted from API requests. However, any field with an + // empty value appearing in NullFields will be sent to the server as + // null. It is an error if a field in this list has a non-empty value. + // This may be used to include null fields in Patch requests. + NullFields []string `json:"-"` +} + +func (s *PolicyBinding) MarshalJSON() ([]byte, error) { + type NoMethod PolicyBinding + raw := NoMethod(*s) + return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields) +} + // PrivateClusterConfig: Configuration options for private clusters. type PrivateClusterConfig struct { // EnablePrivateEndpoint: Whether the master's internal IP address is diff --git a/vendor/google.golang.org/api/internal/cba.go b/vendor/google.golang.org/api/internal/cba.go index 6923d3a71..829383f55 100644 --- a/vendor/google.golang.org/api/internal/cba.go +++ b/vendor/google.golang.org/api/internal/cba.go @@ -274,8 +274,8 @@ func shouldUseS2A(clientCertSource cert.Source, settings *DialSettings) bool { if !isGoogleS2AEnabled() { return false } - // If DefaultMTLSEndpoint is not set, skip S2A. - if settings.DefaultMTLSEndpoint == "" { + // If DefaultMTLSEndpoint is not set and no endpoint override, skip S2A. + if settings.DefaultMTLSEndpoint == "" && settings.Endpoint == "" { return false } // If MTLS is not enabled for this endpoint, skip S2A. diff --git a/vendor/google.golang.org/api/internal/version.go b/vendor/google.golang.org/api/internal/version.go index 1a2b858c8..06fd41703 100644 --- a/vendor/google.golang.org/api/internal/version.go +++ b/vendor/google.golang.org/api/internal/version.go @@ -5,4 +5,4 @@ package internal // Version is the current tagged release of the library. -const Version = "0.136.0" +const Version = "0.138.0" diff --git a/vendor/modules.txt b/vendor/modules.txt index b131b4232..77f918bde 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -143,7 +143,7 @@ github.com/google/mako/internal/go/common github.com/google/mako/internal/quickstore_microservice/proto/quickstore_go_proto github.com/google/mako/proto/quickstore/quickstore_go_proto github.com/google/mako/spec/proto/mako_go_proto -# github.com/google/s2a-go v0.1.4 +# github.com/google/s2a-go v0.1.5 ## explicit; go 1.16 github.com/google/s2a-go github.com/google/s2a-go/fallback @@ -164,6 +164,7 @@ github.com/google/s2a-go/internal/v2 github.com/google/s2a-go/internal/v2/certverifier github.com/google/s2a-go/internal/v2/remotesigner github.com/google/s2a-go/internal/v2/tlsconfigstore +github.com/google/s2a-go/retry github.com/google/s2a-go/stream # github.com/google/uuid v1.3.0 ## explicit @@ -410,7 +411,7 @@ golang.org/x/xerrors/internal # gomodules.xyz/jsonpatch/v2 v2.3.0 ## explicit; go 1.20 gomodules.xyz/jsonpatch/v2 -# google.golang.org/api v0.136.0 +# google.golang.org/api v0.138.0 ## explicit; go 1.19 google.golang.org/api/container/v1beta1 google.golang.org/api/googleapi