github.com/craicoverflow/tyk@v2.9.6-rc3+incompatible/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"path/filepath"
    10  	"runtime"
    11  	"sync"
    12  	"sync/atomic"
    13  	"time"
    14  
    15  	"github.com/kelseyhightower/envconfig"
    16  
    17  	"github.com/TykTechnologies/tyk/apidef"
    18  	logger "github.com/TykTechnologies/tyk/log"
    19  	"github.com/TykTechnologies/tyk/regexp"
    20  )
    21  
    22  type IPsHandleStrategy string
    23  
    24  var (
    25  	log      = logger.Get()
    26  	global   atomic.Value
    27  	globalMu sync.Mutex
    28  
    29  	Default = Config{
    30  		ListenPort:     8080,
    31  		Secret:         "352d20ee67be67f6340b4c0605b044b7",
    32  		TemplatePath:   "templates",
    33  		MiddlewarePath: "middleware",
    34  		AppPath:        "apps/",
    35  		Storage: StorageOptionsConf{
    36  			Type:    "redis",
    37  			Host:    "localhost",
    38  			MaxIdle: 100,
    39  			Port:    6379,
    40  		},
    41  		AnalyticsConfig: AnalyticsConfigConfig{
    42  			IgnoredIPs: make([]string, 0),
    43  		},
    44  		DnsCache: DnsCacheConfig{
    45  			Enabled:                   false,
    46  			TTL:                       dnsCacheDefaultTtl,
    47  			CheckInterval:             dnsCacheDefaultCheckInterval,
    48  			MultipleIPsHandleStrategy: NoCacheStrategy,
    49  		},
    50  	}
    51  )
    52  
    53  const (
    54  	envPrefix = "TYK_GW"
    55  
    56  	dnsCacheDefaultTtl           = 3600
    57  	dnsCacheDefaultCheckInterval = 60
    58  
    59  	PickFirstStrategy IPsHandleStrategy = "pick_first"
    60  	RandomStrategy    IPsHandleStrategy = "random"
    61  	NoCacheStrategy   IPsHandleStrategy = "no_cache"
    62  
    63  	DefaultDashPolicySource     = "service"
    64  	DefaultDashPolicyRecordName = "tyk_policies"
    65  )
    66  
    67  type PoliciesConfig struct {
    68  	PolicySource           string `json:"policy_source"`
    69  	PolicyConnectionString string `json:"policy_connection_string"`
    70  	PolicyRecordName       string `json:"policy_record_name"`
    71  	AllowExplicitPolicyID  bool   `json:"allow_explicit_policy_id"`
    72  }
    73  
    74  type DBAppConfOptionsConfig struct {
    75  	ConnectionString string   `json:"connection_string"`
    76  	NodeIsSegmented  bool     `json:"node_is_segmented"`
    77  	Tags             []string `json:"tags"`
    78  }
    79  
    80  type StorageOptionsConf struct {
    81  	Type                  string            `json:"type"`
    82  	Host                  string            `json:"host"`
    83  	Port                  int               `json:"port"`
    84  	Hosts                 map[string]string `json:"hosts"` // Deprecated: Addrs instead.
    85  	Addrs                 []string          `json:"addrs"`
    86  	MasterName            string            `json:"master_name"`
    87  	Username              string            `json:"username"`
    88  	Password              string            `json:"password"`
    89  	Database              int               `json:"database"`
    90  	MaxIdle               int               `json:"optimisation_max_idle"`
    91  	MaxActive             int               `json:"optimisation_max_active"`
    92  	Timeout               int               `json:"timeout"`
    93  	EnableCluster         bool              `json:"enable_cluster"`
    94  	UseSSL                bool              `json:"use_ssl"`
    95  	SSLInsecureSkipVerify bool              `json:"ssl_insecure_skip_verify"`
    96  }
    97  
    98  type NormalisedURLConfig struct {
    99  	Enabled            bool                 `json:"enabled"`
   100  	NormaliseUUIDs     bool                 `json:"normalise_uuids"`
   101  	NormaliseNumbers   bool                 `json:"normalise_numbers"`
   102  	Custom             []string             `json:"custom_patterns"`
   103  	CompiledPatternSet NormaliseURLPatterns `json:"-"` // see analytics.go
   104  }
   105  
   106  type NormaliseURLPatterns struct {
   107  	UUIDs  *regexp.Regexp
   108  	IDs    *regexp.Regexp
   109  	Custom []*regexp.Regexp
   110  }
   111  
   112  type AnalyticsConfigConfig struct {
   113  	Type                    string              `json:"type"`
   114  	IgnoredIPs              []string            `json:"ignored_ips"`
   115  	EnableDetailedRecording bool                `json:"enable_detailed_recording"`
   116  	EnableGeoIP             bool                `json:"enable_geo_ip"`
   117  	GeoIPDBLocation         string              `json:"geo_ip_db_path"`
   118  	NormaliseUrls           NormalisedURLConfig `json:"normalise_urls"`
   119  	PoolSize                int                 `json:"pool_size"`
   120  	RecordsBufferSize       uint64              `json:"records_buffer_size"`
   121  	StorageExpirationTime   int                 `json:"storage_expiration_time"`
   122  	ignoredIPsCompiled      map[string]bool
   123  }
   124  
   125  type HealthCheckConfig struct {
   126  	EnableHealthChecks      bool  `json:"enable_health_checks"`
   127  	HealthCheckValueTimeout int64 `json:"health_check_value_timeouts"`
   128  }
   129  
   130  type DnsCacheConfig struct {
   131  	Enabled                   bool              `json:"enabled"`
   132  	TTL                       int64             `json:"ttl"`
   133  	CheckInterval             int64             `json:"-" ignored:"true"` //controls cache cleanup interval. By convention shouldn't be exposed to config or env_variable_setup
   134  	MultipleIPsHandleStrategy IPsHandleStrategy `json:"multiple_ips_handle_strategy"`
   135  }
   136  
   137  type MonitorConfig struct {
   138  	EnableTriggerMonitors bool               `json:"enable_trigger_monitors"`
   139  	Config                WebHookHandlerConf `json:"configuration"`
   140  	GlobalTriggerLimit    float64            `json:"global_trigger_limit"`
   141  	MonitorUserKeys       bool               `json:"monitor_user_keys"`
   142  	MonitorOrgKeys        bool               `json:"monitor_org_keys"`
   143  }
   144  
   145  type WebHookHandlerConf struct {
   146  	Method       string            `bson:"method" json:"method"`
   147  	TargetPath   string            `bson:"target_path" json:"target_path"`
   148  	TemplatePath string            `bson:"template_path" json:"template_path"`
   149  	HeaderList   map[string]string `bson:"header_map" json:"header_map"`
   150  	EventTimeout int64             `bson:"event_timeout" json:"event_timeout"`
   151  }
   152  
   153  type SlaveOptionsConfig struct {
   154  	UseRPC                          bool   `json:"use_rpc"`
   155  	UseSSL                          bool   `json:"use_ssl"`
   156  	SSLInsecureSkipVerify           bool   `json:"ssl_insecure_skip_verify"`
   157  	ConnectionString                string `json:"connection_string"`
   158  	RPCKey                          string `json:"rpc_key"`
   159  	APIKey                          string `json:"api_key"`
   160  	EnableRPCCache                  bool   `json:"enable_rpc_cache"`
   161  	BindToSlugsInsteadOfListenPaths bool   `json:"bind_to_slugs"`
   162  	DisableKeySpaceSync             bool   `json:"disable_keyspace_sync"`
   163  	GroupID                         string `json:"group_id"`
   164  	CallTimeout                     int    `json:"call_timeout"`
   165  	PingTimeout                     int    `json:"ping_timeout"`
   166  	RPCPoolSize                     int    `json:"rpc_pool_size"`
   167  }
   168  
   169  type LocalSessionCacheConf struct {
   170  	DisableCacheSessionState bool `json:"disable_cached_session_state"`
   171  	CachedSessionTimeout     int  `json:"cached_session_timeout"`
   172  	CacheSessionEviction     int  `json:"cached_session_eviction"`
   173  }
   174  
   175  type HttpServerOptionsConfig struct {
   176  	OverrideDefaults       bool       `json:"override_defaults"`
   177  	ReadTimeout            int        `json:"read_timeout"`
   178  	WriteTimeout           int        `json:"write_timeout"`
   179  	UseSSL                 bool       `json:"use_ssl"`
   180  	UseLE_SSL              bool       `json:"use_ssl_le"`
   181  	EnableHttp2            bool       `json:"enable_http2"`
   182  	SSLInsecureSkipVerify  bool       `json:"ssl_insecure_skip_verify"`
   183  	EnableWebSockets       bool       `json:"enable_websockets"`
   184  	Certificates           []CertData `json:"certificates"`
   185  	SSLCertificates        []string   `json:"ssl_certificates"`
   186  	ServerName             string     `json:"server_name"`
   187  	MinVersion             uint16     `json:"min_version"`
   188  	FlushInterval          int        `json:"flush_interval"`
   189  	SkipURLCleaning        bool       `json:"skip_url_cleaning"`
   190  	SkipTargetPathEscaping bool       `json:"skip_target_path_escaping"`
   191  	Ciphers                []string   `json:"ssl_ciphers"`
   192  }
   193  
   194  type AuthOverrideConf struct {
   195  	ForceAuthProvider    bool                       `json:"force_auth_provider"`
   196  	AuthProvider         apidef.AuthProviderMeta    `json:"auth_provider"`
   197  	ForceSessionProvider bool                       `json:"force_session_provider"`
   198  	SessionProvider      apidef.SessionProviderMeta `json:"session_provider"`
   199  }
   200  
   201  type UptimeTestsConfigDetail struct {
   202  	FailureTriggerSampleSize int  `json:"failure_trigger_sample_size"`
   203  	TimeWait                 int  `json:"time_wait"`
   204  	CheckerPoolSize          int  `json:"checker_pool_size"`
   205  	EnableUptimeAnalytics    bool `json:"enable_uptime_analytics"`
   206  }
   207  
   208  type UptimeTestsConfig struct {
   209  	Disable     bool                    `json:"disable"`
   210  	PollerGroup string                  `json:"poller_group"`
   211  	Config      UptimeTestsConfigDetail `json:"config"`
   212  }
   213  
   214  type ServiceDiscoveryConf struct {
   215  	DefaultCacheTimeout int `json:"default_cache_timeout"`
   216  }
   217  
   218  type CoProcessConfig struct {
   219  	EnableCoProcess     bool   `json:"enable_coprocess"`
   220  	CoProcessGRPCServer string `json:"coprocess_grpc_server"`
   221  	GRPCRecvMaxSize     int    `json:"grpc_recv_max_size"`
   222  	GRPCSendMaxSize     int    `json:"grpc_send_max_size"`
   223  	PythonPathPrefix    string `json:"python_path_prefix"`
   224  	PythonVersion       string `json:"python_version"`
   225  }
   226  
   227  type CertificatesConfig struct {
   228  	API        []string          `json:"apis"`
   229  	Upstream   map[string]string `json:"upstream"`
   230  	ControlAPI []string          `json:"control_api"`
   231  	Dashboard  []string          `json:"dashboard_api"`
   232  	MDCB       []string          `json:"mdcb_api"`
   233  }
   234  
   235  type SecurityConfig struct {
   236  	PrivateCertificateEncodingSecret string             `json:"private_certificate_encoding_secret"`
   237  	ControlAPIUseMutualTLS           bool               `json:"control_api_use_mutual_tls"`
   238  	PinnedPublicKeys                 map[string]string  `json:"pinned_public_keys"`
   239  	Certificates                     CertificatesConfig `json:"certificates"`
   240  }
   241  
   242  type NewRelicConfig struct {
   243  	AppName    string `json:"app_name"`
   244  	LicenseKey string `json:"license_key"`
   245  }
   246  
   247  type Tracer struct {
   248  	// The name of the tracer to initialize. For instance appdash, to use appdash
   249  	// tracer
   250  	Name string `json:"name"`
   251  
   252  	// If true then this tracer will be activated and all tracing data will be sent
   253  	// to this tracer.NoOp tracer is used otherwise which collects traces but
   254  	// discard them.
   255  	Enabled bool `json:"enabled"`
   256  
   257  	// Key value pairs used to initialize the tracer. These are tracer specific,
   258  	// each tracer requires different options to operate. Please see trace package
   259  	// for options required by supported tracer implementation.
   260  	Options map[string]interface{} `json:"options"`
   261  }
   262  
   263  // ServicePort defines a protocol and port on which a service can bind to
   264  type ServicePort struct {
   265  	Protocol string `json:"protocol"`
   266  	Port     int    `json:"port"`
   267  }
   268  
   269  // PortWhiteList defines ports that will be allowed by the gateway.
   270  type PortWhiteList struct {
   271  	Ranges []PortRange `json:"ranges,omitempty"`
   272  	Ports  []int       `json:"ports,omitempty"`
   273  }
   274  
   275  // Match returns true if port is acceptable from the PortWhiteList.
   276  func (p PortWhiteList) Match(port int) bool {
   277  	for _, v := range p.Ports {
   278  		if port == v {
   279  			return true
   280  		}
   281  	}
   282  	for _, r := range p.Ranges {
   283  		if r.Match(port) {
   284  			return true
   285  		}
   286  	}
   287  	return false
   288  }
   289  
   290  // PortRange defines a range of ports inclusively.
   291  type PortRange struct {
   292  	From int `json:"from"`
   293  	To   int `json:"to"`
   294  }
   295  
   296  // Match returns true if port is within the range
   297  func (r PortRange) Match(port int) bool {
   298  	return r.From <= port && r.To >= port
   299  }
   300  
   301  // Config is the configuration object used by tyk to set up various parameters.
   302  type Config struct {
   303  	// OriginalPath is the path to the config file that was read. If
   304  	// none was found, it's the path to the default config file that
   305  	// was written.
   306  	OriginalPath string `json:"-"`
   307  
   308  	HostName                  string                  `json:"hostname"`
   309  	ListenAddress             string                  `json:"listen_address"`
   310  	ListenPort                int                     `json:"listen_port"`
   311  	ControlAPIHostname        string                  `json:"control_api_hostname"`
   312  	ControlAPIPort            int                     `json:"control_api_port"`
   313  	Secret                    string                  `json:"secret"`
   314  	NodeSecret                string                  `json:"node_secret"`
   315  	PIDFileLocation           string                  `json:"pid_file_location"`
   316  	AllowInsecureConfigs      bool                    `json:"allow_insecure_configs"`
   317  	PublicKeyPath             string                  `json:"public_key_path"`
   318  	AllowRemoteConfig         bool                    `bson:"allow_remote_config" json:"allow_remote_config"`
   319  	Security                  SecurityConfig          `json:"security"`
   320  	HttpServerOptions         HttpServerOptionsConfig `json:"http_server_options"`
   321  	ReloadWaitTime            int                     `bson:"reload_wait_time" json:"reload_wait_time"`
   322  	VersionHeader             string                  `json:"version_header"`
   323  	SuppressRedisSignalReload bool                    `json:"suppress_redis_signal_reload"`
   324  
   325  	// Gateway Security Policies
   326  	HashKeys                bool           `json:"hash_keys"`
   327  	HashKeyFunction         string         `json:"hash_key_function"`
   328  	HashKeyFunctionFallback []string       `json:"hash_key_function_fallback"`
   329  	EnableHashedKeysListing bool           `json:"enable_hashed_keys_listing"`
   330  	MinTokenLength          int            `json:"min_token_length"`
   331  	EnableAPISegregation    bool           `json:"enable_api_segregation"`
   332  	TemplatePath            string         `json:"template_path"`
   333  	Policies                PoliciesConfig `json:"policies"`
   334  	DisablePortWhiteList    bool           `json:"disable_ports_whitelist"`
   335  	// Defines the ports that will be available for the api services to bind to.
   336  	// This is a map of protocol to PortWhiteList. This allows per protocol
   337  	// configurations.
   338  	PortWhiteList map[string]PortWhiteList `json:"ports_whitelist"`
   339  
   340  	// CE Configurations
   341  	AppPath string `json:"app_path"`
   342  
   343  	// Dashboard Configurations
   344  	UseDBAppConfigs          bool                   `json:"use_db_app_configs"`
   345  	DBAppConfOptions         DBAppConfOptionsConfig `json:"db_app_conf_options"`
   346  	Storage                  StorageOptionsConf     `json:"storage"`
   347  	DisableDashboardZeroConf bool                   `json:"disable_dashboard_zeroconf"`
   348  
   349  	// Slave Configurations
   350  	SlaveOptions   SlaveOptionsConfig `json:"slave_options"`
   351  	ManagementNode bool               `json:"management_node"`
   352  	AuthOverride   AuthOverrideConf   `json:"auth_override"`
   353  
   354  	// Rate Limiting Strategy
   355  	EnableNonTransactionalRateLimiter bool    `json:"enable_non_transactional_rate_limiter"`
   356  	EnableSentinelRateLimiter         bool    `json:"enable_sentinel_rate_limiter"`
   357  	EnableRedisRollingLimiter         bool    `json:"enable_redis_rolling_limiter"`
   358  	DRLNotificationFrequency          int     `json:"drl_notification_frequency"`
   359  	DRLEnableSentinelRateLimiter      bool    `json:"drl_enable_sentinel_rate_limiter"`
   360  	DRLThreshold                      float64 `json:"drl_threshold"`
   361  
   362  	// Organization configurations
   363  	EnforceOrgDataAge               bool          `json:"enforce_org_data_age"`
   364  	EnforceOrgDataDetailLogging     bool          `json:"enforce_org_data_detail_logging"`
   365  	EnforceOrgQuotas                bool          `json:"enforce_org_quotas"`
   366  	ExperimentalProcessOrgOffThread bool          `json:"experimental_process_org_off_thread"`
   367  	Monitor                         MonitorConfig `json:"monitor"`
   368  
   369  	// Client-Gateway Configuration
   370  	MaxIdleConns         int   `bson:"max_idle_connections" json:"max_idle_connections"`
   371  	MaxIdleConnsPerHost  int   `bson:"max_idle_connections_per_host" json:"max_idle_connections_per_host"`
   372  	MaxConnTime          int64 `json:"max_conn_time"`
   373  	CloseIdleConnections bool  `json:"close_idle_connections"`
   374  	CloseConnections     bool  `json:"close_connections"`
   375  	EnableCustomDomains  bool  `json:"enable_custom_domains"`
   376  	// If AllowMasterKeys is set to true, session objects (key definitions) that do not have explicit access rights set
   377  	// will be allowed by Tyk. This means that keys that are created have access to ALL APIs, which in many cases is
   378  	// unwanted behaviour unless you are sure about what you are doing.
   379  	AllowMasterKeys bool `json:"allow_master_keys"`
   380  
   381  	// Gateway-Service Configuration
   382  	ServiceDiscovery              ServiceDiscoveryConf `json:"service_discovery"`
   383  	ProxySSLInsecureSkipVerify    bool                 `json:"proxy_ssl_insecure_skip_verify"`
   384  	ProxyEnableHttp2              bool                 `json:"proxy_enable_http2"`
   385  	ProxySSLMinVersion            uint16               `json:"proxy_ssl_min_version"`
   386  	ProxySSLCipherSuites          []string             `json:"proxy_ssl_ciphers"`
   387  	ProxyDefaultTimeout           float64              `json:"proxy_default_timeout"`
   388  	ProxySSLDisableRenegotiation  bool                 `json:"proxy_ssl_disable_renegotiation"`
   389  	ProxyCloseConnections         bool                 `json:"proxy_close_connections"`
   390  	UptimeTests                   UptimeTestsConfig    `json:"uptime_tests"`
   391  	HealthCheck                   HealthCheckConfig    `json:"health_check"`
   392  	OauthRefreshExpire            int64                `json:"oauth_refresh_token_expire"`
   393  	OauthTokenExpire              int32                `json:"oauth_token_expire"`
   394  	OauthTokenExpiredRetainPeriod int32                `json:"oauth_token_expired_retain_period"`
   395  	OauthRedirectUriSeparator     string               `json:"oauth_redirect_uri_separator"`
   396  	OauthErrorStatusCode          int                  `json:"oauth_error_status_code"`
   397  	EnableKeyLogging              bool                 `json:"enable_key_logging"`
   398  	SSLForceCommonNameCheck       bool                 `json:"ssl_force_common_name_check"`
   399  
   400  	// Proxy analytics configuration
   401  	EnableAnalytics bool                  `json:"enable_analytics"`
   402  	AnalyticsConfig AnalyticsConfigConfig `json:"analytics_config"`
   403  
   404  	// Cache
   405  	DnsCache                 DnsCacheConfig        `json:"dns_cache"`
   406  	DisableRegexpCache       bool                  `json:"disable_regexp_cache"`
   407  	RegexpCacheExpire        int32                 `json:"regexp_cache_expire"`
   408  	LocalSessionCache        LocalSessionCacheConf `json:"local_session_cache"`
   409  	EnableSeperateCacheStore bool                  `json:"enable_separate_cache_store"`
   410  	CacheStorage             StorageOptionsConf    `json:"cache_storage"`
   411  
   412  	// Middleware/Plugin Configuration
   413  	EnableBundleDownloader   bool            `bson:"enable_bundle_downloader" json:"enable_bundle_downloader"`
   414  	BundleBaseURL            string          `bson:"bundle_base_url" json:"bundle_base_url"`
   415  	BundleInsecureSkipVerify bool            `bson:"bundle_insecure_skip_verify" json:"bundle_insecure_skip_verify"`
   416  	EnableJSVM               bool            `json:"enable_jsvm"`
   417  	JSVMTimeout              int             `json:"jsvm_timeout"`
   418  	DisableVirtualPathBlobs  bool            `json:"disable_virtual_path_blobs"`
   419  	TykJSPath                string          `json:"tyk_js_path"`
   420  	MiddlewarePath           string          `json:"middleware_path"`
   421  	CoProcessOptions         CoProcessConfig `json:"coprocess_options"`
   422  	IgnoreEndpointCase       bool            `json:"ignore_endpoint_case"`
   423  
   424  	// Monitoring, Logging & Profiling
   425  	LogLevel                string         `json:"log_level"`
   426  	HealthCheckEndpointName string         `json:"health_check_endpoint_name"`
   427  	Tracer                  Tracer         `json:"tracing"`
   428  	NewRelic                NewRelicConfig `json:"newrelic"`
   429  	HTTPProfile             bool           `json:"enable_http_profiler"`
   430  	UseRedisLog             bool           `json:"use_redis_log"`
   431  	SentryCode              string         `json:"sentry_code"`
   432  	SentryLogLevel          string         `json:"sentry_log_level"`
   433  	UseSentry               bool           `json:"use_sentry"`
   434  	UseSyslog               bool           `json:"use_syslog"`
   435  	UseGraylog              bool           `json:"use_graylog"`
   436  	UseLogstash             bool           `json:"use_logstash"`
   437  	GraylogNetworkAddr      string         `json:"graylog_network_addr"`
   438  	LogstashNetworkAddr     string         `json:"logstash_network_addr"`
   439  	SyslogTransport         string         `json:"syslog_transport"`
   440  	LogstashTransport       string         `json:"logstash_transport"`
   441  	SyslogNetworkAddr       string         `json:"syslog_network_addr"`
   442  	StatsdConnectionString  string         `json:"statsd_connection_string"`
   443  	StatsdPrefix            string         `json:"statsd_prefix"`
   444  
   445  	// Event System
   446  	EventHandlers        apidef.EventHandlerMetaConfig         `json:"event_handlers"`
   447  	EventTriggers        map[apidef.TykEvent][]TykEventHandler `json:"event_trigers_defunct"`  // Deprecated: Config.GetEventTriggers instead.
   448  	EventTriggersDefunct map[apidef.TykEvent][]TykEventHandler `json:"event_triggers_defunct"` // Deprecated: Config.GetEventTriggers instead.
   449  
   450  	// TODO: These config options are not documented - What do they do?
   451  	SupressDefaultOrgStore         bool  `json:"suppress_default_org_store"`
   452  	LegacyEnableAllowanceCountdown bool  `bson:"legacy_enable_allowance_countdown" json:"legacy_enable_allowance_countdown"`
   453  	GlobalSessionLifetime          int64 `bson:"global_session_lifetime" json:"global_session_lifetime"`
   454  	ForceGlobalSessionLifetime     bool  `bson:"force_global_session_lifetime" json:"force_global_session_lifetime"`
   455  	HideGeneratorHeader            bool  `json:"hide_generator_header"`
   456  	KV                             struct {
   457  		Consul ConsulConfig `json:"consul"`
   458  		Vault  VaultConfig  `json:"vault"`
   459  	} `json:"kv"`
   460  
   461  	// Secrets are key-value pairs that can be accessed in the dashboard via "secrets://"
   462  	Secrets map[string]string `json:"secrets"`
   463  
   464  	// OverrideMessages is used to override returned API error codes and messages.
   465  	OverrideMessages map[string]TykError `bson:"override_messages" json:"override_messages"`
   466  }
   467  
   468  type TykError struct {
   469  	Message string `json:"message"`
   470  	Code    int    `json:"code"`
   471  }
   472  
   473  // VaultConfig is used to configure the creation of a client
   474  // This is a stripped down version of the Config struct in vault's API client
   475  type VaultConfig struct {
   476  	// Address is the address of the Vault server. This should be a complete
   477  	// URL such as "http://vault.example.com".
   478  	Address string `json:"address"`
   479  
   480  	// AgentAddress is the address of the local Vault agent. This should be a
   481  	// complete URL such as "http://vault.example.com".
   482  	AgentAddress string `json:"agent_address"`
   483  
   484  	// MaxRetries controls the maximum number of times to retry when a vault
   485  	// serer occurs
   486  	MaxRetries int `json:"max_retries"`
   487  
   488  	Timeout time.Duration `json:"timeout"`
   489  
   490  	// Token is the vault root token
   491  	Token string `json:"token"`
   492  
   493  	// KVVersion is the version number of Vault. Usually defaults to 2
   494  	KVVersion int `json:"kv_version"`
   495  }
   496  
   497  // ConsulConfig is used to configure the creation of a client
   498  // This is a stripped down version of the Config struct in consul's API client
   499  type ConsulConfig struct {
   500  	// Address is the address of the Consul server
   501  	Address string `json:"address"`
   502  
   503  	// Scheme is the URI scheme for the Consul server
   504  	Scheme string `json:"scheme"`
   505  
   506  	// Datacenter to use. If not provided, the default agent datacenter is used.
   507  	Datacenter string `json:"datacenter"`
   508  
   509  	// HttpAuth is the auth info to use for http access.
   510  	HttpAuth struct {
   511  		// Username to use for HTTP Basic Authentication
   512  		Username string `json:"username"`
   513  
   514  		// Password to use for HTTP Basic Authentication
   515  		Password string `json:"password"`
   516  	} `json:"http_auth"`
   517  
   518  	// WaitTime limits how long a Watch will block. If not provided,
   519  	// the agent default values will be used.
   520  	WaitTime time.Duration `json:"wait_time"`
   521  
   522  	// Token is used to provide a per-request ACL token
   523  	// which overrides the agent's default token.
   524  	Token string `json:"token"`
   525  
   526  	TLSConfig struct {
   527  		Address string `json:"address"`
   528  
   529  		CAFile string `json:"ca_file"`
   530  
   531  		CAPath string `json:"ca_path"`
   532  
   533  		CertFile string `json:"cert_file"`
   534  
   535  		KeyFile string `json:"key_file"`
   536  
   537  		InsecureSkipVerify bool `json:"insecure_skip_verify"`
   538  	} `json:"tls_config"`
   539  }
   540  
   541  // GetEventTriggers returns event triggers. There was a typo in the json tag.
   542  // To maintain backward compatibility, this solution is chosen.
   543  func (c Config) GetEventTriggers() map[apidef.TykEvent][]TykEventHandler {
   544  	if c.EventTriggersDefunct == nil {
   545  		return c.EventTriggers
   546  	}
   547  
   548  	if c.EventTriggers != nil {
   549  		log.Info("Both event_trigers_defunct and event_triggers_defunct are configured in the config," +
   550  			" event_triggers_defunct will be used.")
   551  	}
   552  
   553  	return c.EventTriggersDefunct
   554  }
   555  
   556  func (c *Config) SetEventTriggers(eventTriggers map[apidef.TykEvent][]TykEventHandler) {
   557  	c.EventTriggersDefunct = eventTriggers
   558  }
   559  
   560  type CertData struct {
   561  	Name     string `json:"domain_name"`
   562  	CertFile string `json:"cert_file"`
   563  	KeyFile  string `json:"key_file"`
   564  }
   565  
   566  // EventMessage is a standard form to send event data to handlers
   567  type EventMessage struct {
   568  	Type      apidef.TykEvent
   569  	Meta      interface{}
   570  	TimeStamp string
   571  }
   572  
   573  // TykEventHandler defines an event handler, e.g. LogMessageEventHandler will handle an event by logging it to stdout.
   574  type TykEventHandler interface {
   575  	Init(interface{}) error
   576  	HandleEvent(EventMessage)
   577  }
   578  
   579  func init() {
   580  	SetGlobal(Config{})
   581  }
   582  
   583  func Global() Config {
   584  	return global.Load().(Config)
   585  }
   586  
   587  func SetGlobal(conf Config) {
   588  	globalMu.Lock()
   589  	defer globalMu.Unlock()
   590  	global.Store(conf)
   591  }
   592  
   593  func WriteConf(path string, conf *Config) error {
   594  	bs, err := json.MarshalIndent(conf, "", "    ")
   595  	if err != nil {
   596  		return err
   597  	}
   598  	return ioutil.WriteFile(path, bs, 0644)
   599  }
   600  
   601  // writeDefault will set conf to the default config and write it to disk
   602  // in path, if the path is non-empty.
   603  func WriteDefault(path string, conf *Config) error {
   604  	_, b, _, _ := runtime.Caller(0)
   605  	configPath := filepath.Dir(b)
   606  	rootPath := filepath.Dir(configPath)
   607  	Default.TemplatePath = filepath.Join(rootPath, "templates")
   608  
   609  	*conf = Default
   610  	if err := envconfig.Process(envPrefix, conf); err != nil {
   611  		return err
   612  	}
   613  	if path == "" {
   614  		return nil
   615  	}
   616  	return WriteConf(path, conf)
   617  }
   618  
   619  // Load will load a configuration file, trying each of the paths given
   620  // and using the first one that is a regular file and can be opened.
   621  //
   622  // If none exists, a default config will be written to the first path in
   623  // the list.
   624  //
   625  // An error will be returned only if any of the paths existed but was
   626  // not a valid config file.
   627  func Load(paths []string, conf *Config) error {
   628  	var r io.Reader
   629  	for _, path := range paths {
   630  		f, err := os.Open(path)
   631  		if err == nil {
   632  			r = f
   633  			conf.OriginalPath = path
   634  			break
   635  		}
   636  		if os.IsNotExist(err) {
   637  			continue
   638  		}
   639  		return err
   640  	}
   641  	if r == nil {
   642  		path := paths[0]
   643  		log.Warnf("No config file found, writing default to %s", path)
   644  		if err := WriteDefault(path, conf); err != nil {
   645  			return err
   646  		}
   647  		log.Info("Loading default configuration...")
   648  		return Load([]string{path}, conf)
   649  	}
   650  	if err := json.NewDecoder(r).Decode(&conf); err != nil {
   651  		return fmt.Errorf("couldn't unmarshal config: %v", err)
   652  	}
   653  	if err := envconfig.Process(envPrefix, conf); err != nil {
   654  		return fmt.Errorf("failed to process config env vars: %v", err)
   655  	}
   656  	if err := processCustom(envPrefix, conf, loadZipkin, loadJaeger); err != nil {
   657  		return fmt.Errorf("failed to process config custom loader: %v", err)
   658  	}
   659  	return nil
   660  }
   661  
   662  func (c *Config) LoadIgnoredIPs() {
   663  	c.AnalyticsConfig.ignoredIPsCompiled = make(map[string]bool, len(c.AnalyticsConfig.IgnoredIPs))
   664  	for _, ip := range c.AnalyticsConfig.IgnoredIPs {
   665  		c.AnalyticsConfig.ignoredIPsCompiled[ip] = true
   666  	}
   667  }
   668  
   669  func (c *Config) StoreAnalytics(ip string) bool {
   670  	if !c.EnableAnalytics {
   671  		return false
   672  	}
   673  
   674  	return !c.AnalyticsConfig.ignoredIPsCompiled[ip]
   675  }
   676  
   677  // processCustom these are custom functions for loadign config values. They will
   678  // be called in the order they are passed. Any function that returns an error
   679  // then that error will be returned and no further processing will be
   680  // happenning.
   681  func processCustom(prefix string, c *Config, custom ...func(prefix string, c *Config) error) error {
   682  	for _, fn := range custom {
   683  		if err := fn(prefix, c); err != nil {
   684  			return err
   685  		}
   686  	}
   687  	return nil
   688  }