blob: 393d3541d55fb9c35bce3d82fbe0bbe4da5cc0a1 [file] [edit]
// Copyright 2025 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package rsproxy
import (
"flag"
"strings"
"time"
"github.com/bazelbuild/remote-apis-sdks/go/pkg/credshelper"
"github.com/bazelbuild/remote-apis-sdks/go/pkg/moreflag"
"google.golang.org/grpc/credentials"
)
// ClientConfig holds all the configurable parameters for the rsproxy client.
type ClientConfig struct {
// ResultStore/CAS service options
ResultStoreService string
CASService string
ResultStoreInstance string
CASInstance string
// Authentication and RPC options
CredFile string
UseApplicationDefaultCreds bool
UseGCECredentials bool
CredentialsHelper string
CredentialsHelperArgs string
UseRPCCredentials bool
UseExternalAuthToken bool
ServiceNoSecurity bool
ServiceNoAuth bool
RemoteHeaders map[string][]string
MaxConcurrentRequests uint
TLSServerName string
ResultStoreTLSServerName string
CASTLSServerName string
TLSCACert string
TLSClientAuthCert string
TLSClientAuthKey string
RPCTimeoutsStrings map[string]string
KeepAliveTime time.Duration
KeepAliveTimeout time.Duration
KeepAlivePermitWithoutStream bool
DebugUploadReqs bool
ProxyDoneFile string
}
// RegisterFlags registers the client-related flags with the given FlagSet.
func (c *ClientConfig) RegisterFlags(fs *flag.FlagSet) {
fs.StringVar(&c.ResultStoreService, "rs_service", "", "The ResultStore service to dial via gRPC, including port, such as 'localhost:8790' or 'resultstore.googleapis.com:443'")
fs.StringVar(&c.CASService, "cas_service", "", "The CAS service to dial via gRPC, including port, such as 'localhost:8790' or 'remotebuildexecution.googleapis.com:443'")
fs.StringVar(&c.ResultStoreInstance, "rs_instance", "", "The instance ID to target when uploading to ResultStore via gRPC (e.g., projects/$PROJECT/instances/default_instance for Google ResultStore).")
fs.StringVar(&c.CASInstance, "cas_instance", "", "The instance ID to target when uploading content to CAS via gRPC (e.g., projects/$PROJECT/instances/default_instance for Google RBE CAS).")
fs.StringVar(&c.CredFile, "credential_file", "", "The name of a file that contains service account credentials to use when streaming build events. Used only if --use_application_default_credentials and --use_gce_credentials are false.")
fs.BoolVar(&c.UseApplicationDefaultCreds, "use_application_default_credentials", false, "If true, use application default credentials to connect to build event service. See https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login")
fs.BoolVar(&c.UseGCECredentials, "use_gce_credentials", false, "If true (and --use_application_default_credentials is false), use the default GCE credentials to authenticate with build event service.")
fs.StringVar(&c.CredentialsHelper, credshelper.CredshelperPathFlag, "", "Path to the credentials helper binary. If given execrel://, looks for the `credshelper` binary in the same folder as the current executable.")
fs.StringVar(&c.CredentialsHelperArgs, credshelper.CredshelperArgsFlag, "", "Arguments for the credentials helper, separated by space.")
fs.BoolVar(&c.UseRPCCredentials, "use_rpc_credentials", true, "If false, no per-RPC credentials will be used (disables --credential_file, --use_application_default_credentials, and --use_gce_credentials.")
fs.BoolVar(&c.UseExternalAuthToken, "use_external_auth_token", false, "If true, se an externally provided auth token, given via PerRPCCreds when the SDK is initialized.")
fs.BoolVar(&c.ServiceNoSecurity, "service_no_security", false, "If true, do not use TLS or authentication when connecting to the gRPC service.")
fs.BoolVar(&c.ServiceNoAuth, "service_no_auth", false, "If true, do not authenticate with the service (implied by --service_no_security).")
fs.Var((*moreflag.StringListMapValue)(&c.RemoteHeaders), "remote_headers", "Comma-separated headers to pass with each RPC in the form key=value.")
fs.UintVar(&c.MaxConcurrentRequests, "max_concurrent_requests_per_conn", DefaultMaxConcurrentRequests, "Maximum number of concurrent RPCs on a single gRPC connection.")
fs.StringVar(&c.TLSServerName, "tls_server_name", "", "Override the TLS server name for both ResultStore and CAS")
fs.StringVar(&c.ResultStoreTLSServerName, "rs_tls_server_name", "", "Override the TLS server name for ResultStore (this defaults to --tls_server_name)")
fs.StringVar(&c.CASTLSServerName, "cas_tls_server_name", "", "Override the TLS server name for CAS (this defaults to --tls_server_name)")
fs.StringVar(&c.TLSCACert, "tls_ca_cert", "", "Load TLS CA certificates from this file")
fs.StringVar(&c.TLSClientAuthCert, "tls_client_auth_cert", "", "Certificate to use when using mTLS to connect to the RBE service.")
fs.StringVar(&c.TLSClientAuthKey, "tls_client_auth_key", "", "Key to use when using mTLS to connect to the RBE service.")
fs.Var((*moreflag.StringMapValue)(&c.RPCTimeoutsStrings), "rpc_timeouts", "Comma-separated key value pairs in the form rpc_name=timeout. The key for default RPC is named default. 0 indicates no timeout. Example: GetActionResult=500ms,Execute=0,default=10s.")
fs.DurationVar(&c.KeepAliveTime, "grpc_keepalive_time", 0*time.Second, "After a duration of this time if the client doesn't see any activity it pings the server to see if the transport is still alive. If zero or not set, the mechanism is off.")
fs.DurationVar(&c.KeepAliveTimeout, "grpc_keepalive_timeout", 20*time.Second, "After having pinged for keepalive check, the client waits for a duration of Timeout and if no activity is seen even after that the connection is closed. Default is 20s.")
fs.BoolVar(&c.KeepAlivePermitWithoutStream, "grpc_keepalive_permit_without_stream", false, "If true, client sends keepalive pings even with no active RPCs; otherwise, doesn't send pings even if time and timeout are set. Default is false.")
fs.BoolVar(&c.DebugUploadReqs, "debug_upload_reqs", false, "If true, send upload requests in batches of 1 for easier debugging.")
fs.StringVar(&c.ProxyDoneFile, "proxy_done_file", "", "If set, a file will be created at this path to signal that the server has finished internal data processing and is ready for shutdown.")
}
// ConfigureRPCCreds prepares and returns PerRPCCredentials based on the ClientConfig.
func (c *ClientConfig) ConfigureRPCCreds() (credentials.PerRPCCredentials, error) {
var pCreds credentials.PerRPCCredentials
if c.CredentialsHelper != "" {
creds, err := credshelper.NewExternalCredentials(c.CredentialsHelper, strings.Fields(c.CredentialsHelperArgs))
if err != nil {
return nil, err
}
pCreds = creds.PerRPCCreds()
// glog.Infof("Using credentials helper at %v", c.CredentialsHelper) // glog not available here
}
return pCreds, nil
}