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 }