go.temporal.io/server@v1.23.0/common/config/config.go (about) 1 // The MIT License 2 // 3 // Copyright (c) 2020 Temporal Technologies Inc. All rights reserved. 4 // 5 // Copyright (c) 2020 Uber Technologies, Inc. 6 // 7 // Permission is hereby granted, free of charge, to any person obtaining a copy 8 // of this software and associated documentation files (the "Software"), to deal 9 // in the Software without restriction, including without limitation the rights 10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 // copies of the Software, and to permit persons to whom the Software is 12 // furnished to do so, subject to the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be included in 15 // all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 // THE SOFTWARE. 24 25 package config 26 27 import ( 28 "bytes" 29 "fmt" 30 "strings" 31 "time" 32 33 "gopkg.in/yaml.v3" 34 35 "go.temporal.io/server/common/auth" 36 "go.temporal.io/server/common/cluster" 37 "go.temporal.io/server/common/dynamicconfig" 38 "go.temporal.io/server/common/log" 39 "go.temporal.io/server/common/masker" 40 "go.temporal.io/server/common/metrics" 41 "go.temporal.io/server/common/persistence/visibility/store/elasticsearch/client" 42 "go.temporal.io/server/common/primitives" 43 "go.temporal.io/server/common/telemetry" 44 ) 45 46 type ( 47 // Config contains the configuration for a set of temporal services 48 Config struct { 49 // Global is process-wide service-related configuration 50 Global Global `yaml:"global"` 51 // Persistence contains the configuration for temporal datastores 52 Persistence Persistence `yaml:"persistence"` 53 // Log is the logging config 54 Log log.Config `yaml:"log"` 55 // ClusterMetadata is the config containing all valid clusters and active cluster 56 ClusterMetadata *cluster.Config `yaml:"clusterMetadata"` 57 // DCRedirectionPolicy contains the frontend datacenter redirection policy 58 DCRedirectionPolicy DCRedirectionPolicy `yaml:"dcRedirectionPolicy"` 59 // Services is a map of service name to service config items 60 Services map[string]Service `yaml:"services"` 61 // Archival is the config for archival 62 Archival Archival `yaml:"archival"` 63 // PublicClient is config for connecting to temporal frontend 64 PublicClient PublicClient `yaml:"publicClient"` 65 // DynamicConfigClient is the config for setting up the file based dynamic config client 66 // Filepath should be relative to the root directory 67 DynamicConfigClient *dynamicconfig.FileBasedClientConfig `yaml:"dynamicConfigClient"` 68 // NamespaceDefaults is the default config for every namespace 69 NamespaceDefaults NamespaceDefaults `yaml:"namespaceDefaults"` 70 // ExporterConfig allows the specification of process-wide OTEL exporters 71 ExporterConfig telemetry.ExportConfig `yaml:"otel"` 72 } 73 74 // Service contains the service specific config items 75 Service struct { 76 // RPC is the rpc configuration 77 RPC RPC `yaml:"rpc"` 78 } 79 80 // PProf contains the config items for the pprof utility 81 PProf struct { 82 // Port is the port on which the PProf will bind to 83 Port int `yaml:"port"` 84 // Host defaults to `localhost` but can be overriden 85 // for instance in the case of dual stack IPv4/IPv6 86 Host string `yaml:"host"` 87 } 88 89 // RPC contains the rpc config items 90 RPC struct { 91 // GRPCPort is the port on which gRPC will listen 92 GRPCPort int `yaml:"grpcPort"` 93 // Port used for membership listener 94 MembershipPort int `yaml:"membershipPort"` 95 // BindOnLocalHost is true if localhost is the bind address 96 // if neither BindOnLocalHost nor BindOnIP are set then an 97 // an attempt to discover an address is made 98 BindOnLocalHost bool `yaml:"bindOnLocalHost"` 99 // BindOnIP can be used to bind service on specific ip (eg. `0.0.0.0` or `::`) 100 // check net.ParseIP for supported syntax 101 // mutually exclusive with `BindOnLocalHost` option 102 BindOnIP string `yaml:"bindOnIP"` 103 // HTTPPort is the port on which HTTP will listen. If unset/0, HTTP will be 104 // disabled. This setting only applies to the frontend service. 105 HTTPPort int `yaml:"httpPort"` 106 // HTTPAdditionalForwardedHeaders adds additional headers to the default set 107 // forwarded from HTTP to gRPC. 108 HTTPAdditionalForwardedHeaders []string `yaml:"httpAdditionalForwardedHeaders"` 109 } 110 111 // Global contains config items that apply process-wide to all services 112 Global struct { 113 // Membership is the ringpop related configuration 114 Membership Membership `yaml:"membership"` 115 // PProf is the PProf configuration 116 PProf PProf `yaml:"pprof"` 117 // TLS controls the communication encryption configuration 118 TLS RootTLS `yaml:"tls"` 119 // Metrics is the metrics subsystem configuration 120 Metrics *metrics.Config `yaml:"metrics"` 121 // Settings for authentication and authorization 122 Authorization Authorization `yaml:"authorization"` 123 } 124 125 // RootTLS contains all TLS settings for the Temporal server 126 RootTLS struct { 127 // Internode controls backend service (history, matching, internal-frontend) 128 // communication TLS settings. 129 Internode GroupTLS `yaml:"internode"` 130 // Frontend controls frontend server TLS settings. To control system worker -> frontend 131 // TLS, use the SystemWorker field. (Frontend.Client is accepted for backwards 132 // compatibility.) 133 Frontend GroupTLS `yaml:"frontend"` 134 // SystemWorker controls TLS setting for System Workers connecting to Frontend. 135 SystemWorker WorkerTLS `yaml:"systemWorker"` 136 // RemoteFrontendClients controls TLS setting for talking to remote cluster. 137 RemoteClusters map[string]GroupTLS `yaml:"remoteClusters"` 138 // ExpirationChecks defines settings for periodic checks for expiration of certificates 139 ExpirationChecks CertExpirationValidation `yaml:"expirationChecks"` 140 // Interval between refreshes of certificates loaded from files 141 RefreshInterval time.Duration `yaml:"refreshInterval"` 142 } 143 144 // GroupTLS contains an instance client and server TLS settings 145 GroupTLS struct { 146 // Client handles client TLS settings 147 Client ClientTLS `yaml:"client"` 148 // Server handles the server (listener) TLS settings 149 Server ServerTLS `yaml:"server"` 150 151 // PerHostOverrides contains per-hostname TLS settings that 152 // are used for external clients connecting to the Temporal Cluster on that 153 // specific hostname. Host names are case insensitive. Optional. If not present, 154 // uses configuration supplied by Server field. 155 PerHostOverrides map[string]ServerTLS `yaml:"hostOverrides"` 156 } 157 158 // ServerTLS contains items to load server TLS configuration 159 ServerTLS struct { 160 // The path to the file containing the PEM-encoded public key of the certificate to use. 161 CertFile string `yaml:"certFile"` 162 // The path to the file containing the PEM-encoded private key of the certificate to use. 163 KeyFile string `yaml:"keyFile"` 164 // A list of paths to files containing the PEM-encoded public key of the Certificate Authorities you wish to trust for client authentication. 165 // This value is ignored if `requireClientAuth` is not enabled. Cannot specify both ClientCAFiles and ClientCAData 166 ClientCAFiles []string `yaml:"clientCaFiles"` 167 168 // Base64 equivalents of the above artifacts. 169 // You cannot specify both a Data and a File for the same artifact (e.g. setting CertFile and CertData) 170 CertData string `yaml:"certData"` 171 KeyData string `yaml:"keyData"` 172 ClientCAData []string `yaml:"clientCaData"` 173 174 // Requires clients to authenticate with a certificate when connecting, otherwise known as mutual TLS. 175 RequireClientAuth bool `yaml:"requireClientAuth"` 176 } 177 178 // ClientTLS contains TLS configuration for clients within the Temporal Cluster to connect to Temporal nodes. 179 ClientTLS struct { 180 // DNS name to validate against for server to server connections. 181 // Required when TLS is enabled in a multi-host cluster. 182 // This name should be referenced by the certificate specified in the ServerTLS section. 183 ServerName string `yaml:"serverName"` 184 185 // If you want to verify the temporal server hostname and server cert, then you should turn this on 186 // This option is basically equivalent to InSecureSkipVerify 187 // See InSecureSkipVerify in http://golang.org/pkg/crypto/tls/ for more info 188 DisableHostVerification bool `yaml:"disableHostVerification"` 189 190 // Optional - A list of paths to files containing the PEM-encoded public key of the Certificate Authorities that are used to validate the server's TLS certificate 191 // You cannot specify both RootCAFiles and RootCAData 192 RootCAFiles []string `yaml:"rootCaFiles"` 193 194 // Optional - A list of base64 PEM-encoded public keys of the Certificate Authorities that are used to validate the server's TLS certificate. 195 // You cannot specify both RootCAFiles and RootCAData 196 RootCAData []string `yaml:"rootCaData"` 197 198 // Optional - Use TLS even is neither client certificate nor root CAs are configured 199 // This is for non-mTLS cases when client validates serve against a set of trusted CA certificates configured in the environment 200 ForceTLS bool `yaml:"forceTLS"` 201 } 202 203 // WorkerTLS contains TLS configuration for system workers within the Temporal Cluster to connect to Temporal frontend. 204 WorkerTLS struct { 205 // The path to the file containing the PEM-encoded public key of the client certificate to use by system workers. 206 CertFile string `yaml:"certFile"` 207 // The path to the file containing the PEM-encoded private key of the client certificate to use by system workers. 208 KeyFile string `yaml:"keyFile"` 209 // Base64 equivalents of the above artifacts. 210 // You cannot specify both a Data and a File for the same artifact (e.g. setting CertFile and CertData) 211 CertData string `yaml:"certData"` 212 KeyData string `yaml:"keyData"` 213 214 // Client TLS settings for system workers 215 Client ClientTLS `yaml:"client"` 216 } 217 218 // CertExpirationValidation contains settings for periodic checks of TLS certificate expiration 219 CertExpirationValidation struct { 220 // Log warnings for certificates expiring during this time window from now 221 WarningWindow time.Duration `yaml:"warningWindow"` 222 // Log error for certificates expiring during this time window from now 223 ErrorWindow time.Duration `yaml:"errorWindow"` 224 // Interval between checks for certificate expiration 225 CheckInterval time.Duration `yaml:"checkInterval"` 226 } 227 228 // Membership contains config items related to the membership layer of temporal 229 Membership struct { 230 // MaxJoinDuration is the max wait time to join the gossip ring 231 MaxJoinDuration time.Duration `yaml:"maxJoinDuration"` 232 // BroadcastAddress is used as the address that is communicated to remote nodes to connect on. 233 // This is generally used when BindOnIP would be the same across several nodes (ie: `0.0.0.0` or `::`) 234 // and for nat traversal scenarios. Check net.ParseIP for supported syntax 235 BroadcastAddress string `yaml:"broadcastAddress"` 236 } 237 238 // Persistence contains the configuration for data store / persistence layer 239 Persistence struct { 240 // DefaultStore is the name of the default data store to use 241 DefaultStore string `yaml:"defaultStore" validate:"nonzero"` 242 // VisibilityStore is the name of the datastore to be used for visibility records 243 VisibilityStore string `yaml:"visibilityStore"` 244 // SecondaryVisibilityStore is the name of the secondary datastore to be used for visibility records 245 SecondaryVisibilityStore string `yaml:"secondaryVisibilityStore"` 246 // DEPRECATED: use VisibilityStore key instead of AdvancedVisibilityStore 247 // AdvancedVisibilityStore is the name of the datastore to be used for visibility records 248 AdvancedVisibilityStore string `yaml:"advancedVisibilityStore"` 249 // NumHistoryShards is the desired number of history shards. This config doesn't 250 // belong here, needs refactoring 251 NumHistoryShards int32 `yaml:"numHistoryShards" validate:"nonzero"` 252 // DataStores contains the configuration for all datastores 253 DataStores map[string]DataStore `yaml:"datastores"` 254 // TransactionSizeLimit is the largest allowed transaction size 255 TransactionSizeLimit dynamicconfig.IntPropertyFn `yaml:"-" json:"-"` 256 } 257 258 // DataStore is the configuration for a single datastore 259 DataStore struct { 260 // FaultInjection contains the config for fault injector wrapper. 261 FaultInjection *FaultInjection `yaml:"faultInjection"` 262 // Cassandra contains the config for a cassandra datastore 263 Cassandra *Cassandra `yaml:"cassandra"` 264 // SQL contains the config for a SQL based datastore 265 SQL *SQL `yaml:"sql"` 266 // Custom contains the config for custom datastore implementation 267 CustomDataStoreConfig *CustomDatastoreConfig `yaml:"customDatastore"` 268 // ElasticSearch contains the config for a ElasticSearch datastore 269 Elasticsearch *client.Config `yaml:"elasticsearch"` 270 } 271 272 FaultInjection struct { 273 // Rate is the probability that we will return an error from any call to any datastore. 274 // The value should be between 0.0 and 1.0. 275 // The fault injector will inject different errors depending on the data store and method. See the 276 // implementation for details. 277 // This field is ignored if Targets is non-empty. 278 Rate float64 `yaml:"rate"` 279 280 // Targets is a mapping of data store name to a targeted fault injection config for that data store. 281 // If Targets is non-empty, then Rate is ignored. 282 // Here is an example config for targeted fault injection. This config will inject errors into the 283 // UpdateShard method of the ShardStore at a rate of 100%. No other methods will be affected. 284 /* 285 targets: 286 dataStores: 287 ShardStore: 288 methods: 289 UpdateShard: 290 seed: 42 291 errors: 292 ShardOwnershipLostError: 1.0 # all UpdateShard calls will fail with ShardOwnershipLostError 293 */ 294 // This will cause the UpdateShard method of the ShardStore to always return ShardOwnershipLostError. 295 Targets FaultInjectionTargets `yaml:"targets"` 296 } 297 298 // FaultInjectionTargets is the set of targets for fault injection. A target is a method of a data store. 299 FaultInjectionTargets struct { 300 // DataStores is a map of datastore name to fault injection config. 301 // Use this to configure fault injection for specific datastores. The key is the name of the datastore, 302 // e.g. "ShardStore". See DataStoreName for the list of valid datastore names. 303 DataStores map[DataStoreName]FaultInjectionDataStoreConfig `yaml:"dataStores"` 304 } 305 306 // DataStoreName is the name of a datastore, e.g. "ShardStore". The full list is defined later in this file. 307 DataStoreName string 308 309 // FaultInjectionDataStoreConfig is the fault injection config for a single datastore, e.g., the ShardStore. 310 FaultInjectionDataStoreConfig struct { 311 // Methods is a map of data store method name to a fault injection config for that method. 312 // We create an error generator that infers the method name from the call stack using reflection. 313 // For example, if a test with targeted fault injection enabled calls ShardStore.UpdateShard, then 314 // we fetch the error generator from this map using the key "UpdateShard". 315 // The key is the name of the method to inject faults for. 316 // The value is the config for that method. 317 Methods map[string]FaultInjectionMethodConfig `yaml:"methods"` 318 } 319 320 // FaultInjectionMethodConfig is the fault injection config for a single method of a data store. 321 FaultInjectionMethodConfig struct { 322 // Errors is a map of error type to probability of returning that error. 323 // For example: `ShardOwnershipLostError: 0.1` will cause the method to return a ShardOwnershipLostError 10% of 324 // the time. 325 // The other 90% of the time, the method will call the underlying datastore. 326 // If there are multiple errors for a method, the probability of each error is independent of the others. 327 // For example, if there are two errors with probabilities 0.1 and 0.2, then the first error will be returned 328 // 10% of the time, the second error will be returned 20% of the time, 329 // and the underlying method will be called 70% of the time. 330 Errors map[string]float64 `yaml:"errors"` 331 332 // Seed is the seed for the random number generator used to sample faults from the Errors map. You can use this 333 // to make the fault injection deterministic. 334 // If the test config does not set this to a non-zero number, the fault injector will set it to the current time 335 // in nanoseconds. 336 Seed int64 `yaml:"seed"` 337 } 338 339 // Cassandra contains configuration to connect to Cassandra cluster 340 Cassandra struct { 341 // Hosts is a csv of cassandra endpoints 342 Hosts string `yaml:"hosts" validate:"nonzero"` 343 // Port is the cassandra port used for connection by gocql client 344 Port int `yaml:"port"` 345 // User is the cassandra user used for authentication by gocql client 346 User string `yaml:"user"` 347 // Password is the cassandra password used for authentication by gocql client 348 Password string `yaml:"password"` 349 // keyspace is the cassandra keyspace 350 Keyspace string `yaml:"keyspace" validate:"nonzero"` 351 // Datacenter is the data center filter arg for cassandra 352 Datacenter string `yaml:"datacenter"` 353 // MaxConns is the max number of connections to this datastore for a single keyspace 354 MaxConns int `yaml:"maxConns"` 355 // ConnectTimeout is a timeout for initial dial to cassandra server (default: 600 milliseconds) 356 ConnectTimeout time.Duration `yaml:"connectTimeout"` 357 // TLS configuration 358 TLS *auth.TLS `yaml:"tls"` 359 // Consistency configuration (defaults to LOCAL_QUORUM / LOCAL_SERIAL for all stores if this field not set) 360 Consistency *CassandraStoreConsistency `yaml:"consistency"` 361 // DisableInitialHostLookup instructs the gocql client to connect only using the supplied hosts 362 DisableInitialHostLookup bool `yaml:"disableInitialHostLookup"` 363 // AddressTranslator translates Cassandra IP addresses, used for cases when IP addresses gocql driver returns are not accessible from the server 364 AddressTranslator *CassandraAddressTranslator `yaml:"addressTranslator"` 365 } 366 367 // CassandraStoreConsistency enables you to set the consistency settings for each Cassandra Persistence Store for Temporal 368 CassandraStoreConsistency struct { 369 // Default defines the consistency level for ALL stores. 370 // Defaults to LOCAL_QUORUM and LOCAL_SERIAL if not set 371 Default *CassandraConsistencySettings `yaml:"default"` 372 } 373 374 CassandraAddressTranslator struct { 375 // Translator defines name of translator implementation to use for Cassandra address translation 376 Translator string `yaml:"translator"` 377 // Options map of options for address translator implementation 378 Options map[string]string `yaml:"options"` 379 } 380 381 // CassandraConsistencySettings sets the default consistency level for regular & serial queries to Cassandra. 382 CassandraConsistencySettings struct { 383 // Consistency sets the default consistency level. Values identical to gocql Consistency values. (defaults to LOCAL_QUORUM if not set). 384 Consistency string `yaml:"consistency"` 385 // SerialConsistency sets the consistency for the serial prtion of queries. Values identical to gocql SerialConsistency values. (defaults to LOCAL_SERIAL if not set) 386 SerialConsistency string `yaml:"serialConsistency"` 387 } 388 389 // SQL is the configuration for connecting to a SQL backed datastore 390 SQL struct { 391 // User is the username to be used for the conn 392 User string `yaml:"user"` 393 // Password is the password corresponding to the user name 394 Password string `yaml:"password"` 395 // PluginName is the name of SQL plugin 396 PluginName string `yaml:"pluginName" validate:"nonzero"` 397 // DatabaseName is the name of SQL database to connect to 398 DatabaseName string `yaml:"databaseName" validate:"nonzero"` 399 // ConnectAddr is the remote addr of the database 400 ConnectAddr string `yaml:"connectAddr" validate:"nonzero"` 401 // ConnectProtocol is the protocol that goes with the ConnectAddr ex - tcp, unix 402 ConnectProtocol string `yaml:"connectProtocol" validate:"nonzero"` 403 // ConnectAttributes is a set of key-value attributes to be sent as part of connect data_source_name url 404 ConnectAttributes map[string]string `yaml:"connectAttributes"` 405 // MaxConns the max number of connections to this datastore 406 MaxConns int `yaml:"maxConns"` 407 // MaxIdleConns is the max number of idle connections to this datastore 408 MaxIdleConns int `yaml:"maxIdleConns"` 409 // MaxConnLifetime is the maximum time a connection can be alive 410 MaxConnLifetime time.Duration `yaml:"maxConnLifetime"` 411 // EXPERIMENTAL - TaskScanPartitions is the number of partitions to sequentially scan during ListTaskQueue operations. 412 // This is used for in a sharded sql database such as Vitess for heavy task workloads to minimize scatter gather. 413 // The default value for this param is 1, and should not be configured without a thorough understanding of what this does. 414 TaskScanPartitions int `yaml:"taskScanPartitions"` 415 // TLS is the configuration for TLS connections 416 TLS *auth.TLS `yaml:"tls"` 417 } 418 419 // CustomDatastoreConfig is the configuration for connecting to a custom datastore that is not supported by temporal core 420 CustomDatastoreConfig struct { 421 // Name of the custom datastore 422 Name string `yaml:"name"` 423 // Options to be used by AbstractDatastoreFactory implementation 424 Options map[string]any `yaml:"options"` 425 } 426 427 // Replicator describes the configuration of replicator 428 Replicator struct{} 429 430 // ReplicationTaskProcessorConfig is the config for replication task processor. 431 ReplicationTaskProcessorConfig struct { 432 NoTaskInitialWaitIntervalSecs int `yaml:"noTaskInitialWaitIntervalSecs"` 433 NoTaskWaitBackoffCoefficient float64 `yaml:"noTaskWaitBackoffCoefficient"` 434 NoTaskMaxWaitIntervalSecs int `yaml:"noTaskMaxWaitIntervalSecs"` 435 } 436 437 // DCRedirectionPolicy contains the frontend datacenter redirection policy 438 DCRedirectionPolicy struct { 439 Policy string `yaml:"policy"` 440 } 441 442 // Archival contains the config for archival 443 Archival struct { 444 // History is the config for the history archival 445 History HistoryArchival `yaml:"history"` 446 // Visibility is the config for visibility archival 447 Visibility VisibilityArchival `yaml:"visibility"` 448 } 449 450 // HistoryArchival contains the config for history archival 451 HistoryArchival struct { 452 // State is the state of history archival either: enabled, disabled, or paused 453 State string `yaml:"state"` 454 // EnableRead whether history can be read from archival 455 EnableRead bool `yaml:"enableRead"` 456 // Provider contains the config for all history archivers 457 Provider *HistoryArchiverProvider `yaml:"provider"` 458 } 459 460 // HistoryArchiverProvider contains the config for all history archivers 461 HistoryArchiverProvider struct { 462 Filestore *FilestoreArchiver `yaml:"filestore"` 463 Gstorage *GstorageArchiver `yaml:"gstorage"` 464 S3store *S3Archiver `yaml:"s3store"` 465 } 466 467 // VisibilityArchival contains the config for visibility archival 468 VisibilityArchival struct { 469 // State is the state of visibility archival either: enabled, disabled, or paused 470 State string `yaml:"state"` 471 // EnableRead whether visibility can be read from archival 472 EnableRead bool `yaml:"enableRead"` 473 // Provider contains the config for all visibility archivers 474 Provider *VisibilityArchiverProvider `yaml:"provider"` 475 } 476 477 // VisibilityArchiverProvider contains the config for all visibility archivers 478 VisibilityArchiverProvider struct { 479 Filestore *FilestoreArchiver `yaml:"filestore"` 480 S3store *S3Archiver `yaml:"s3store"` 481 Gstorage *GstorageArchiver `yaml:"gstorage"` 482 } 483 484 // FilestoreArchiver contain the config for filestore archiver 485 FilestoreArchiver struct { 486 FileMode string `yaml:"fileMode"` 487 DirMode string `yaml:"dirMode"` 488 } 489 490 // GstorageArchiver contain the config for google storage archiver 491 GstorageArchiver struct { 492 CredentialsPath string `yaml:"credentialsPath"` 493 } 494 495 // S3Archiver contains the config for S3 archiver 496 S3Archiver struct { 497 Region string `yaml:"region"` 498 Endpoint *string `yaml:"endpoint"` 499 S3ForcePathStyle bool `yaml:"s3ForcePathStyle"` 500 LogLevel uint `yaml:"logLevel"` 501 } 502 503 // PublicClient is the config for internal nodes (history/matching/worker) connecting to 504 // frontend. There are three methods of connecting: 505 // 1. Use membership to locate "internal-frontend" and connect to them using the Internode 506 // TLS config (which can be "no TLS"). This is recommended for deployments that use an 507 // Authorizer and ClaimMapper. To use this, leave this section out of your config, and 508 // make sure there is an "internal-frontend" section in Services. 509 // 2. Use membership to locate "frontend" and connect to them using the Frontend TLS config 510 // (which can be "no TLS"). This is recommended for deployments that don't use an 511 // Authorizer or ClaimMapper, or have implemented a custom ClaimMapper that correctly 512 // identifies the system worker using mTLS and assigns it an Admin-level claim. 513 // To use this, leave this section out of your config and make sure there is _no_ 514 // "internal-frontend" section in Services. 515 // 3. Connect to an explicit endpoint using the SystemWorker (falling back to Frontend) TLS 516 // config (which can be "no TLS"). You can use this if you want to force frontend 517 // connections to go through an external load balancer. If you use this with a 518 // ClaimMapper+Authorizer, you need to ensure that your ClaimMapper assigns Admin 519 // claims to worker nodes, and your Authorizer correctly handles those claims. 520 PublicClient struct { 521 // HostPort is the host port to connect on. Host can be DNS name. See the above 522 // comment: in many situations you can leave this empty. 523 HostPort string `yaml:"hostPort"` 524 // Force selection of either the "internode" or "frontend" TLS configs for these 525 // connections (only those two strings are valid). 526 ForceTLSConfig string `yaml:"forceTLSConfig"` 527 } 528 529 // NamespaceDefaults is the default config for each namespace 530 NamespaceDefaults struct { 531 // Archival is the default archival config for each namespace 532 Archival ArchivalNamespaceDefaults `yaml:"archival"` 533 } 534 535 // ArchivalNamespaceDefaults is the default archival config for each namespace 536 ArchivalNamespaceDefaults struct { 537 // History is the namespace default history archival config for each namespace 538 History HistoryArchivalNamespaceDefaults `yaml:"history"` 539 // Visibility is the namespace default visibility archival config for each namespace 540 Visibility VisibilityArchivalNamespaceDefaults `yaml:"visibility"` 541 } 542 543 // HistoryArchivalNamespaceDefaults is the default history archival config for each namespace 544 HistoryArchivalNamespaceDefaults struct { 545 // State is the namespace default state of history archival: enabled or disabled 546 State string `yaml:"state"` 547 // URI is the namespace default URI for history archiver 548 URI string `yaml:"URI"` 549 } 550 551 // VisibilityArchivalNamespaceDefaults is the default visibility archival config for each namespace 552 VisibilityArchivalNamespaceDefaults struct { 553 // State is the namespace default state of visibility archival: enabled or disabled 554 State string `yaml:"state"` 555 // URI is the namespace default URI for visibility archiver 556 URI string `yaml:"URI"` 557 } 558 559 Authorization struct { 560 // Signing key provider for validating JWT tokens 561 JWTKeyProvider JWTKeyProvider `yaml:"jwtKeyProvider"` 562 PermissionsClaimName string `yaml:"permissionsClaimName"` 563 // Empty string for noopAuthorizer or "default" for defaultAuthorizer 564 Authorizer string `yaml:"authorizer"` 565 // Empty string for noopClaimMapper or "default" for defaultJWTClaimMapper 566 ClaimMapper string `yaml:"claimMapper"` 567 // Name of main auth header to pass to ClaimMapper (as `AuthToken`). Defaults to `authorization`. 568 AuthHeaderName string `yaml:"authHeaderName"` 569 // Name of extra auth header to pass to ClaimMapper (as `ExtraData`). Defaults to `authorization-extras`. 570 AuthExtraHeaderName string `yaml:"authExtraHeaderName"` 571 } 572 573 // @@@SNIPSTART temporal-common-service-config-jwtkeyprovider 574 // Contains the config for signing key provider for validating JWT tokens 575 JWTKeyProvider struct { 576 KeySourceURIs []string `yaml:"keySourceURIs"` 577 RefreshInterval time.Duration `yaml:"refreshInterval"` 578 } 579 // @@@SNIPEND 580 ) 581 582 const ( 583 ShardStoreName DataStoreName = "ShardStore" 584 TaskStoreName DataStoreName = "TaskStore" 585 MetadataStoreName DataStoreName = "MetadataStore" 586 ExecutionStoreName DataStoreName = "ExecutionStore" 587 QueueName DataStoreName = "Queue" 588 QueueV2Name DataStoreName = "QueueV2" 589 ClusterMDStoreName DataStoreName = "ClusterMDStore" 590 ) 591 592 const ( 593 ForceTLSConfigAuto = "" 594 ForceTLSConfigInternode = "internode" 595 ForceTLSConfigFrontend = "frontend" 596 ) 597 598 // Validate validates this config 599 func (c *Config) Validate() error { 600 if err := c.Persistence.Validate(); err != nil { 601 return err 602 } 603 604 if err := c.Archival.Validate(&c.NamespaceDefaults.Archival); err != nil { 605 return err 606 } 607 608 _, hasIFE := c.Services[string(primitives.InternalFrontendService)] 609 if hasIFE && (c.PublicClient.HostPort != "" || c.PublicClient.ForceTLSConfig != "") { 610 return fmt.Errorf("when using internal-frontend, publicClient must be empty") 611 } 612 613 switch c.PublicClient.ForceTLSConfig { 614 case ForceTLSConfigAuto, ForceTLSConfigInternode, ForceTLSConfigFrontend: 615 default: 616 return fmt.Errorf("invalid value for publicClient.forceTLSConfig: %q", c.PublicClient.ForceTLSConfig) 617 } 618 619 return nil 620 } 621 622 // String converts the config object into a string 623 func (c *Config) String() string { 624 var buf bytes.Buffer 625 encoder := yaml.NewEncoder(&buf) 626 encoder.SetIndent(2) 627 _ = encoder.Encode(c) 628 maskedYaml, _ := masker.MaskYaml(buf.String(), masker.DefaultYAMLFieldNames) 629 return maskedYaml 630 } 631 632 func (r *GroupTLS) IsServerEnabled() bool { 633 return r.Server.KeyFile != "" || r.Server.KeyData != "" 634 } 635 636 func (r *GroupTLS) IsClientEnabled() bool { 637 return len(r.Client.RootCAFiles) > 0 || len(r.Client.RootCAData) > 0 || 638 r.Client.ForceTLS 639 } 640 641 func (p *JWTKeyProvider) HasSourceURIsConfigured() bool { 642 if len(p.KeySourceURIs) == 0 { 643 return false 644 } 645 for _, uri := range p.KeySourceURIs { 646 if strings.TrimSpace(uri) != "" { 647 return true 648 } 649 } 650 return false 651 }