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  }