github.com/bazelbuild/remote-apis-sdks@v0.0.0-20240425170053-8a36686a6350/go/pkg/flags/flags.go (about) 1 // Package flags provides a convenient way to initialize the remote client from flags. 2 package flags 3 4 import ( 5 "context" 6 "flag" 7 "time" 8 9 "github.com/bazelbuild/remote-apis-sdks/go/pkg/balancer" 10 "github.com/bazelbuild/remote-apis-sdks/go/pkg/client" 11 "github.com/bazelbuild/remote-apis-sdks/go/pkg/moreflag" 12 "google.golang.org/grpc" 13 "google.golang.org/grpc/keepalive" 14 15 log "github.com/golang/glog" 16 ) 17 18 var ( 19 // The flags credential_file, use_application_default_credentials, and use_gce_credentials 20 // determine the client identity that is used to authenticate with remote execution. 21 // One of the following must be true for client authentication to work, and they are used in 22 // this order of preference: 23 // - the use_application_default_credentials flag must be set to true, or 24 // - the use_gce_credentials must be set to true, or 25 // - the credential_file flag must be set to point to a valid credential file 26 27 // CredFile is the name of a file that contains service account credentials to use when calling 28 // remote execution. Used only if --use_application_default_credentials and --use_gce_credentials 29 // are false. 30 CredFile = flag.String("credential_file", "", "The name of a file that contains service account credentials to use when calling remote execution. Used only if --use_application_default_credentials and --use_gce_credentials are false.") 31 // UseApplicationDefaultCreds is whether to use application default credentials to connect to 32 // remote execution. See 33 // https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login 34 UseApplicationDefaultCreds = flag.Bool("use_application_default_credentials", false, "If true, use application default credentials to connect to remote execution. See https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login") 35 // UseGCECredentials is whether to use the default GCE credentials to authenticate with remote 36 // execution. --use_application_default_credentials must be false. 37 UseGCECredentials = flag.Bool("use_gce_credentials", false, "If true (and --use_application_default_credentials is false), use the default GCE credentials to authenticate with remote execution.") 38 // UseRPCCredentials can be set to false to disable all per-RPC credentials. 39 UseRPCCredentials = flag.Bool("use_rpc_credentials", true, "If false, no per-RPC credentials will be used (disables --credential_file, --use_application_default_credentials, and --use_gce_credentials.") 40 // UseExternalAuthToken specifies whether to use an externally provided auth token, given via PerRPCCreds dial option, should be used. 41 UseExternalAuthToken = flag.Bool("use_external_auth_token", false, "If true, se an externally provided auth token, given via PerRPCCreds when the SDK is initialized.") 42 // Service represents the host (and, if applicable, port) of the remote execution service. 43 Service = flag.String("service", "", "The remote execution service to dial when calling via gRPC, including port, such as 'localhost:8790' or 'remotebuildexecution.googleapis.com:443'") 44 // ServiceNoSecurity can be set to connect to the gRPC service without TLS and without authentication (enables --service_no_auth). 45 ServiceNoSecurity = flag.Bool("service_no_security", false, "If true, do not use TLS or authentication when connecting to the gRPC service.") 46 // ServiceNoAuth can be set to disable authentication while still using TLS. 47 ServiceNoAuth = flag.Bool("service_no_auth", false, "If true, do not authenticate with the service (implied by --service_no_security).") 48 // CASService represents the host (and, if applicable, port) of the CAS service, if different from the remote execution service. 49 CASService = flag.String("cas_service", "", "The CAS service to dial when calling via gRPC, including port, such as 'localhost:8790' or 'remotebuildexecution.googleapis.com:443'") 50 // Instance gives the instance of remote execution to test (in 51 // projects/[PROJECT_ID]/instances/[INSTANCE_NAME] format for Google RBE). 52 Instance = flag.String("instance", "", "The instance ID to target when calling remote execution via gRPC (e.g., projects/$PROJECT/instances/default_instance for Google RBE).") 53 // CASConcurrency specifies the maximum number of concurrent upload & download RPCs that can be in flight. 54 CASConcurrency = flag.Int("cas_concurrency", client.DefaultCASConcurrency, "Num concurrent upload / download RPCs that the SDK is allowed to do.") 55 // MaxConcurrentRequests denotes the maximum number of concurrent RPCs on a single gRPC connection. 56 MaxConcurrentRequests = flag.Uint("max_concurrent_requests_per_conn", client.DefaultMaxConcurrentRequests, "Maximum number of concurrent RPCs on a single gRPC connection.") 57 // MaxConcurrentStreams denotes the maximum number of concurrent stream RPCs on a single gRPC connection. 58 MaxConcurrentStreams = flag.Uint("max_concurrent_streams_per_conn", client.DefaultMaxConcurrentStreams, "Maximum number of concurrent stream RPCs on a single gRPC connection.") 59 // TLSServerName overrides the server name sent in the TLS session. 60 TLSServerName = flag.String("tls_server_name", "", "Override the TLS server name") 61 // TLSCACert loads CA certificates from a file 62 TLSCACert = flag.String("tls_ca_cert", "", "Load TLS CA certificates from this file") 63 // TLSClientAuthCert sets the public key in PEM format for using mTLS auth to connect to the RBE service. 64 TLSClientAuthCert = flag.String("tls_client_auth_cert", "", "Certificate to use when using mTLS to connect to the RBE service.") 65 // TLSClientAuthKey sets the private key for using mTLS auth to connect to the RBE service. 66 TLSClientAuthKey = flag.String("tls_client_auth_key", "", "Key to use when using mTLS to connect to the RBE service.") 67 // StartupCapabilities specifies whether to self-configure based on remote server capabilities on startup. 68 StartupCapabilities = flag.Bool("startup_capabilities", true, "Whether to self-configure based on remote server capabilities on startup.") 69 // RPCTimeouts stores the per-RPC timeout values. 70 RPCTimeouts map[string]string 71 // KeepAliveTime specifies gRPCs keepalive time parameter. 72 KeepAliveTime = flag.Duration("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.") 73 // KeepAliveTimeout specifies gRPCs keepalive timeout parameter. 74 KeepAliveTimeout = flag.Duration("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.") 75 // KeepAlivePermitWithoutStream specifies gRPCs keepalive permitWithoutStream parameter. 76 KeepAlivePermitWithoutStream = flag.Bool("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.") 77 ) 78 79 func init() { 80 // MinConnections denotes the minimum number of gRPC sub-connections the gRPC balancer should create during SDK initialization. 81 flag.IntVar(&balancer.MinConnections, "min_grpc_connections", balancer.DefaultMinConnections, "Minimum number of gRPC sub-connections the gRPC balancer should create during SDK initialization.") 82 // RPCTimeouts stores the per-RPC timeout values. The flag allows users to override the defaults 83 // set in client.DefaultRPCTimeouts. This is in order to not force the users to familiarize 84 // themselves with every RPC, otherwise it is easy to accidentally enforce a timeout on 85 // WaitExecution, for example. 86 flag.Var((*moreflag.StringMapValue)(&RPCTimeouts), "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.") 87 } 88 89 // NewClientFromFlags connects to a remote execution service and returns a client suitable for higher-level 90 // functionality. It uses the flags from above to configure the connection to remote execution. 91 func NewClientFromFlags(ctx context.Context, opts ...client.Opt) (*client.Client, error) { 92 opts = append(opts, []client.Opt{client.CASConcurrency(*CASConcurrency), client.StartupCapabilities(*StartupCapabilities)}...) 93 if len(RPCTimeouts) > 0 { 94 timeouts := make(map[string]time.Duration) 95 for rpc, d := range client.DefaultRPCTimeouts { 96 timeouts[rpc] = d 97 } 98 // Override the defaults with flags, but do not replace. 99 for rpc, s := range RPCTimeouts { 100 d, err := time.ParseDuration(s) 101 if err != nil { 102 return nil, err 103 } 104 timeouts[rpc] = d 105 } 106 opts = append(opts, client.RPCTimeouts(timeouts)) 107 } 108 var perRPCCreds *client.PerRPCCreds 109 tOpts := []client.Opt{} 110 for _, opt := range opts { 111 switch opt.(type) { 112 case *client.PerRPCCreds: 113 perRPCCreds = (opt).(*(client.PerRPCCreds)) 114 default: 115 tOpts = append(tOpts, opt) 116 } 117 } 118 opts = tOpts 119 120 dialOpts := make([]grpc.DialOption, 0) 121 if *KeepAliveTime > 0*time.Second { 122 params := keepalive.ClientParameters{ 123 Time: *KeepAliveTime, 124 Timeout: *KeepAliveTimeout, 125 PermitWithoutStream: *KeepAlivePermitWithoutStream, 126 } 127 log.V(1).Infof("KeepAlive params = %v", params) 128 dialOpts = append(dialOpts, grpc.WithKeepaliveParams(params)) 129 } 130 return client.NewClient(ctx, *Instance, client.DialParams{ 131 Service: *Service, 132 NoSecurity: *ServiceNoSecurity, 133 NoAuth: *ServiceNoAuth, 134 CASService: *CASService, 135 CredFile: *CredFile, 136 DialOpts: dialOpts, 137 UseApplicationDefault: *UseApplicationDefaultCreds, 138 UseComputeEngine: *UseGCECredentials, 139 UseExternalAuthToken: *UseExternalAuthToken, 140 ExternalPerRPCCreds: perRPCCreds, 141 TransportCredsOnly: !*UseRPCCredentials, 142 TLSServerName: *TLSServerName, 143 TLSCACertFile: *TLSCACert, 144 TLSClientAuthCert: *TLSClientAuthCert, 145 TLSClientAuthKey: *TLSClientAuthKey, 146 MaxConcurrentRequests: uint32(*MaxConcurrentRequests), 147 MaxConcurrentStreams: uint32(*MaxConcurrentStreams), 148 }, opts...) 149 }