storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/config/notify/parse.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2019 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package notify 18 19 import ( 20 "context" 21 "crypto/tls" 22 "crypto/x509" 23 "errors" 24 "net/http" 25 "strconv" 26 "strings" 27 "time" 28 29 "storj.io/minio/cmd/config" 30 "storj.io/minio/cmd/logger" 31 "storj.io/minio/pkg/env" 32 "storj.io/minio/pkg/event" 33 "storj.io/minio/pkg/event/target" 34 xnet "storj.io/minio/pkg/net" 35 ) 36 37 const ( 38 formatNamespace = "namespace" 39 ) 40 41 // ErrTargetsOffline - Indicates single/multiple target failures. 42 var ErrTargetsOffline = errors.New("one or more targets are offline. Please use `mc admin info --json` to check the offline targets") 43 44 // TestNotificationTargets is similar to GetNotificationTargets() 45 // avoids explicit registration. 46 func TestNotificationTargets(ctx context.Context, cfg config.Config, transport *http.Transport, targetIDs []event.TargetID) error { 47 test := true 48 returnOnTargetError := true 49 targets, err := RegisterNotificationTargets(ctx, cfg, transport, targetIDs, test, returnOnTargetError) 50 if err == nil { 51 // Close all targets since we are only testing connections. 52 for _, t := range targets.TargetMap() { 53 _ = t.Close() 54 } 55 } 56 57 return err 58 } 59 60 // GetNotificationTargets registers and initializes all notification 61 // targets, returns error if any. 62 func GetNotificationTargets(ctx context.Context, cfg config.Config, transport *http.Transport, test bool) (*event.TargetList, error) { 63 returnOnTargetError := false 64 return RegisterNotificationTargets(ctx, cfg, transport, nil, test, returnOnTargetError) 65 } 66 67 // RegisterNotificationTargets - returns TargetList which contains enabled targets in serverConfig. 68 // A new notification target is added like below 69 // * Add a new target in pkg/event/target package. 70 // * Add newly added target configuration to serverConfig.Notify.<TARGET_NAME>. 71 // * Handle the configuration in this function to create/add into TargetList. 72 func RegisterNotificationTargets(ctx context.Context, cfg config.Config, transport *http.Transport, targetIDs []event.TargetID, test bool, returnOnTargetError bool) (*event.TargetList, error) { 73 targetList, err := FetchRegisteredTargets(ctx, cfg, transport, test, returnOnTargetError) 74 if err != nil { 75 return targetList, err 76 } 77 78 if test { 79 // Verify if user is trying to disable already configured 80 // notification targets, based on their target IDs 81 for _, targetID := range targetIDs { 82 if !targetList.Exists(targetID) { 83 return nil, config.Errorf( 84 "Unable to disable configured targets '%v'", 85 targetID) 86 } 87 } 88 } 89 90 return targetList, nil 91 } 92 93 // FetchRegisteredTargets - Returns a set of configured TargetList 94 // If `returnOnTargetError` is set to true, The function returns when a target initialization fails 95 // Else, the function will return a complete TargetList irrespective of errors 96 func FetchRegisteredTargets(ctx context.Context, cfg config.Config, transport *http.Transport, test bool, returnOnTargetError bool) (_ *event.TargetList, err error) { 97 targetList := event.NewTargetList() 98 var targetsOffline bool 99 100 defer func() { 101 // Automatically close all connections to targets when an error occur. 102 // Close all the targets if returnOnTargetError is set 103 // Else, close only the failed targets 104 if err != nil && returnOnTargetError { 105 for _, t := range targetList.TargetMap() { 106 _ = t.Close() 107 } 108 } 109 }() 110 111 if err = checkValidNotificationKeys(cfg); err != nil { 112 return nil, err 113 } 114 115 amqpTargets, err := GetNotifyAMQP(cfg[config.NotifyAMQPSubSys]) 116 if err != nil { 117 return nil, err 118 } 119 120 esTargets, err := GetNotifyES(cfg[config.NotifyESSubSys], transport) 121 if err != nil { 122 return nil, err 123 } 124 125 kafkaTargets, err := GetNotifyKafka(cfg[config.NotifyKafkaSubSys]) 126 if err != nil { 127 return nil, err 128 } 129 130 mqttTargets, err := GetNotifyMQTT(cfg[config.NotifyMQTTSubSys], transport.TLSClientConfig.RootCAs) 131 if err != nil { 132 return nil, err 133 } 134 135 mysqlTargets, err := GetNotifyMySQL(cfg[config.NotifyMySQLSubSys]) 136 if err != nil { 137 return nil, err 138 } 139 140 natsTargets, err := GetNotifyNATS(cfg[config.NotifyNATSSubSys], transport.TLSClientConfig.RootCAs) 141 if err != nil { 142 return nil, err 143 } 144 145 nsqTargets, err := GetNotifyNSQ(cfg[config.NotifyNSQSubSys]) 146 if err != nil { 147 return nil, err 148 } 149 150 postgresTargets, err := GetNotifyPostgres(cfg[config.NotifyPostgresSubSys]) 151 if err != nil { 152 return nil, err 153 } 154 155 redisTargets, err := GetNotifyRedis(cfg[config.NotifyRedisSubSys]) 156 if err != nil { 157 return nil, err 158 } 159 160 webhookTargets, err := GetNotifyWebhook(cfg[config.NotifyWebhookSubSys], transport) 161 if err != nil { 162 return nil, err 163 } 164 165 for id, args := range amqpTargets { 166 if !args.Enable { 167 continue 168 } 169 newTarget, err := target.NewAMQPTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 170 if err != nil { 171 targetsOffline = true 172 if returnOnTargetError { 173 return nil, err 174 } 175 _ = newTarget.Close() 176 } 177 178 if err = targetList.Add(newTarget); err != nil { 179 logger.LogIf(context.Background(), err) 180 if returnOnTargetError { 181 return nil, err 182 } 183 } 184 } 185 186 for id, args := range esTargets { 187 if !args.Enable { 188 continue 189 } 190 newTarget, err := target.NewElasticsearchTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 191 if err != nil { 192 targetsOffline = true 193 if returnOnTargetError { 194 return nil, err 195 } 196 _ = newTarget.Close() 197 } 198 if err = targetList.Add(newTarget); err != nil { 199 logger.LogIf(context.Background(), err) 200 if returnOnTargetError { 201 return nil, err 202 } 203 } 204 } 205 206 for id, args := range kafkaTargets { 207 if !args.Enable { 208 continue 209 } 210 args.TLS.RootCAs = transport.TLSClientConfig.RootCAs 211 newTarget, err := target.NewKafkaTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 212 if err != nil { 213 targetsOffline = true 214 if returnOnTargetError { 215 return nil, err 216 } 217 _ = newTarget.Close() 218 } 219 if err = targetList.Add(newTarget); err != nil { 220 logger.LogIf(context.Background(), err) 221 if returnOnTargetError { 222 return nil, err 223 } 224 } 225 } 226 227 for id, args := range mqttTargets { 228 if !args.Enable { 229 continue 230 } 231 args.RootCAs = transport.TLSClientConfig.RootCAs 232 newTarget, err := target.NewMQTTTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 233 if err != nil { 234 targetsOffline = true 235 if returnOnTargetError { 236 return nil, err 237 } 238 _ = newTarget.Close() 239 } 240 if err = targetList.Add(newTarget); err != nil { 241 logger.LogIf(context.Background(), err) 242 if returnOnTargetError { 243 return nil, err 244 } 245 } 246 } 247 248 for id, args := range mysqlTargets { 249 if !args.Enable { 250 continue 251 } 252 newTarget, err := target.NewMySQLTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 253 if err != nil { 254 targetsOffline = true 255 if returnOnTargetError { 256 return nil, err 257 } 258 _ = newTarget.Close() 259 } 260 if err = targetList.Add(newTarget); err != nil { 261 logger.LogIf(context.Background(), err) 262 if returnOnTargetError { 263 return nil, err 264 } 265 } 266 } 267 268 for id, args := range natsTargets { 269 if !args.Enable { 270 continue 271 } 272 newTarget, err := target.NewNATSTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 273 if err != nil { 274 targetsOffline = true 275 if returnOnTargetError { 276 return nil, err 277 } 278 _ = newTarget.Close() 279 } 280 if err = targetList.Add(newTarget); err != nil { 281 logger.LogIf(context.Background(), err) 282 if returnOnTargetError { 283 return nil, err 284 } 285 } 286 } 287 288 for id, args := range nsqTargets { 289 if !args.Enable { 290 continue 291 } 292 newTarget, err := target.NewNSQTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 293 if err != nil { 294 targetsOffline = true 295 if returnOnTargetError { 296 return nil, err 297 } 298 _ = newTarget.Close() 299 } 300 if err = targetList.Add(newTarget); err != nil { 301 logger.LogIf(context.Background(), err) 302 if returnOnTargetError { 303 return nil, err 304 } 305 } 306 } 307 308 for id, args := range postgresTargets { 309 if !args.Enable { 310 continue 311 } 312 newTarget, err := target.NewPostgreSQLTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 313 if err != nil { 314 targetsOffline = true 315 if returnOnTargetError { 316 return nil, err 317 } 318 _ = newTarget.Close() 319 } 320 if err = targetList.Add(newTarget); err != nil { 321 logger.LogIf(context.Background(), err) 322 if returnOnTargetError { 323 return nil, err 324 } 325 } 326 } 327 328 for id, args := range redisTargets { 329 if !args.Enable { 330 continue 331 } 332 newTarget, err := target.NewRedisTarget(id, args, ctx.Done(), logger.LogOnceIf, test) 333 if err != nil { 334 targetsOffline = true 335 if returnOnTargetError { 336 return nil, err 337 } 338 _ = newTarget.Close() 339 } 340 if err = targetList.Add(newTarget); err != nil { 341 logger.LogIf(context.Background(), err) 342 if returnOnTargetError { 343 return nil, err 344 } 345 } 346 } 347 348 for id, args := range webhookTargets { 349 if !args.Enable { 350 continue 351 } 352 newTarget, err := target.NewWebhookTarget(ctx, id, args, logger.LogOnceIf, transport, test) 353 if err != nil { 354 targetsOffline = true 355 if returnOnTargetError { 356 return nil, err 357 } 358 _ = newTarget.Close() 359 } 360 if err = targetList.Add(newTarget); err != nil { 361 logger.LogIf(context.Background(), err) 362 if returnOnTargetError { 363 return nil, err 364 } 365 } 366 } 367 368 if targetsOffline { 369 return targetList, ErrTargetsOffline 370 } 371 372 return targetList, nil 373 } 374 375 // DefaultNotificationKVS - default notification list of kvs. 376 var ( 377 DefaultNotificationKVS = map[string]config.KVS{ 378 config.NotifyAMQPSubSys: DefaultAMQPKVS, 379 config.NotifyKafkaSubSys: DefaultKafkaKVS, 380 config.NotifyMQTTSubSys: DefaultMQTTKVS, 381 config.NotifyMySQLSubSys: DefaultMySQLKVS, 382 config.NotifyNATSSubSys: DefaultNATSKVS, 383 config.NotifyNSQSubSys: DefaultNSQKVS, 384 config.NotifyPostgresSubSys: DefaultPostgresKVS, 385 config.NotifyRedisSubSys: DefaultRedisKVS, 386 config.NotifyWebhookSubSys: DefaultWebhookKVS, 387 config.NotifyESSubSys: DefaultESKVS, 388 } 389 ) 390 391 func checkValidNotificationKeys(cfg config.Config) error { 392 for subSys, tgt := range cfg { 393 validKVS, ok := DefaultNotificationKVS[subSys] 394 if !ok { 395 continue 396 } 397 for tname, kv := range tgt { 398 subSysTarget := subSys 399 if tname != config.Default { 400 subSysTarget = subSys + config.SubSystemSeparator + tname 401 } 402 if v, ok := kv.Lookup(config.Enable); ok && v == config.EnableOn { 403 if err := config.CheckValidKeys(subSysTarget, kv, validKVS); err != nil { 404 return err 405 } 406 } 407 } 408 } 409 return nil 410 } 411 412 func mergeTargets(cfgTargets map[string]config.KVS, envname string, defaultKVS config.KVS) map[string]config.KVS { 413 newCfgTargets := make(map[string]config.KVS) 414 for _, e := range env.List(envname) { 415 tgt := strings.TrimPrefix(e, envname+config.Default) 416 if tgt == envname { 417 tgt = config.Default 418 } 419 newCfgTargets[tgt] = defaultKVS 420 } 421 for tgt, kv := range cfgTargets { 422 newCfgTargets[tgt] = kv 423 } 424 return newCfgTargets 425 } 426 427 // DefaultKakfaKVS - default KV for kafka target 428 var ( 429 DefaultKafkaKVS = config.KVS{ 430 config.KV{ 431 Key: config.Enable, 432 Value: config.EnableOff, 433 }, 434 config.KV{ 435 Key: target.KafkaTopic, 436 Value: "", 437 }, 438 config.KV{ 439 Key: target.KafkaBrokers, 440 Value: "", 441 }, 442 config.KV{ 443 Key: target.KafkaSASLUsername, 444 Value: "", 445 }, 446 config.KV{ 447 Key: target.KafkaSASLPassword, 448 Value: "", 449 }, 450 config.KV{ 451 Key: target.KafkaSASLMechanism, 452 Value: "plain", 453 }, 454 config.KV{ 455 Key: target.KafkaClientTLSCert, 456 Value: "", 457 }, 458 config.KV{ 459 Key: target.KafkaClientTLSKey, 460 Value: "", 461 }, 462 config.KV{ 463 Key: target.KafkaTLSClientAuth, 464 Value: "0", 465 }, 466 config.KV{ 467 Key: target.KafkaSASL, 468 Value: config.EnableOff, 469 }, 470 config.KV{ 471 Key: target.KafkaTLS, 472 Value: config.EnableOff, 473 }, 474 config.KV{ 475 Key: target.KafkaTLSSkipVerify, 476 Value: config.EnableOff, 477 }, 478 config.KV{ 479 Key: target.KafkaQueueLimit, 480 Value: "0", 481 }, 482 config.KV{ 483 Key: target.KafkaQueueDir, 484 Value: "", 485 }, 486 config.KV{ 487 Key: target.KafkaVersion, 488 Value: "", 489 }, 490 } 491 ) 492 493 // GetNotifyKafka - returns a map of registered notification 'kafka' targets 494 func GetNotifyKafka(kafkaKVS map[string]config.KVS) (map[string]target.KafkaArgs, error) { 495 kafkaTargets := make(map[string]target.KafkaArgs) 496 for k, kv := range mergeTargets(kafkaKVS, target.EnvKafkaEnable, DefaultKafkaKVS) { 497 enableEnv := target.EnvKafkaEnable 498 if k != config.Default { 499 enableEnv = enableEnv + config.Default + k 500 } 501 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 502 if err != nil { 503 return nil, err 504 } 505 if !enabled { 506 continue 507 } 508 var brokers []xnet.Host 509 brokersEnv := target.EnvKafkaBrokers 510 if k != config.Default { 511 brokersEnv = brokersEnv + config.Default + k 512 } 513 kafkaBrokers := env.Get(brokersEnv, kv.Get(target.KafkaBrokers)) 514 if len(kafkaBrokers) == 0 { 515 return nil, config.Errorf("kafka 'brokers' cannot be empty") 516 } 517 for _, s := range strings.Split(kafkaBrokers, config.ValueSeparator) { 518 var host *xnet.Host 519 host, err = xnet.ParseHost(s) 520 if err != nil { 521 break 522 } 523 brokers = append(brokers, *host) 524 } 525 if err != nil { 526 return nil, err 527 } 528 529 queueLimitEnv := target.EnvKafkaQueueLimit 530 if k != config.Default { 531 queueLimitEnv = queueLimitEnv + config.Default + k 532 } 533 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.KafkaQueueLimit)), 10, 64) 534 if err != nil { 535 return nil, err 536 } 537 538 clientAuthEnv := target.EnvKafkaTLSClientAuth 539 if k != config.Default { 540 clientAuthEnv = clientAuthEnv + config.Default + k 541 } 542 clientAuth, err := strconv.Atoi(env.Get(clientAuthEnv, kv.Get(target.KafkaTLSClientAuth))) 543 if err != nil { 544 return nil, err 545 } 546 547 topicEnv := target.EnvKafkaTopic 548 if k != config.Default { 549 topicEnv = topicEnv + config.Default + k 550 } 551 552 queueDirEnv := target.EnvKafkaQueueDir 553 if k != config.Default { 554 queueDirEnv = queueDirEnv + config.Default + k 555 } 556 557 versionEnv := target.EnvKafkaVersion 558 if k != config.Default { 559 versionEnv = versionEnv + config.Default + k 560 } 561 562 kafkaArgs := target.KafkaArgs{ 563 Enable: enabled, 564 Brokers: brokers, 565 Topic: env.Get(topicEnv, kv.Get(target.KafkaTopic)), 566 QueueDir: env.Get(queueDirEnv, kv.Get(target.KafkaQueueDir)), 567 QueueLimit: queueLimit, 568 Version: env.Get(versionEnv, kv.Get(target.KafkaVersion)), 569 } 570 571 tlsEnableEnv := target.EnvKafkaTLS 572 if k != config.Default { 573 tlsEnableEnv = tlsEnableEnv + config.Default + k 574 } 575 tlsSkipVerifyEnv := target.EnvKafkaTLSSkipVerify 576 if k != config.Default { 577 tlsSkipVerifyEnv = tlsSkipVerifyEnv + config.Default + k 578 } 579 580 tlsClientTLSCertEnv := target.EnvKafkaClientTLSCert 581 if k != config.Default { 582 tlsClientTLSCertEnv = tlsClientTLSCertEnv + config.Default + k 583 } 584 585 tlsClientTLSKeyEnv := target.EnvKafkaClientTLSKey 586 if k != config.Default { 587 tlsClientTLSKeyEnv = tlsClientTLSKeyEnv + config.Default + k 588 } 589 590 kafkaArgs.TLS.Enable = env.Get(tlsEnableEnv, kv.Get(target.KafkaTLS)) == config.EnableOn 591 kafkaArgs.TLS.SkipVerify = env.Get(tlsSkipVerifyEnv, kv.Get(target.KafkaTLSSkipVerify)) == config.EnableOn 592 kafkaArgs.TLS.ClientAuth = tls.ClientAuthType(clientAuth) 593 594 kafkaArgs.TLS.ClientTLSCert = env.Get(tlsClientTLSCertEnv, kv.Get(target.KafkaClientTLSCert)) 595 kafkaArgs.TLS.ClientTLSKey = env.Get(tlsClientTLSKeyEnv, kv.Get(target.KafkaClientTLSKey)) 596 597 saslEnableEnv := target.EnvKafkaSASLEnable 598 if k != config.Default { 599 saslEnableEnv = saslEnableEnv + config.Default + k 600 } 601 saslUsernameEnv := target.EnvKafkaSASLUsername 602 if k != config.Default { 603 saslUsernameEnv = saslUsernameEnv + config.Default + k 604 } 605 saslPasswordEnv := target.EnvKafkaSASLPassword 606 if k != config.Default { 607 saslPasswordEnv = saslPasswordEnv + config.Default + k 608 } 609 saslMechanismEnv := target.EnvKafkaSASLMechanism 610 if k != config.Default { 611 saslMechanismEnv = saslMechanismEnv + config.Default + k 612 } 613 kafkaArgs.SASL.Enable = env.Get(saslEnableEnv, kv.Get(target.KafkaSASL)) == config.EnableOn 614 kafkaArgs.SASL.User = env.Get(saslUsernameEnv, kv.Get(target.KafkaSASLUsername)) 615 kafkaArgs.SASL.Password = env.Get(saslPasswordEnv, kv.Get(target.KafkaSASLPassword)) 616 kafkaArgs.SASL.Mechanism = env.Get(saslMechanismEnv, kv.Get(target.KafkaSASLMechanism)) 617 618 if err = kafkaArgs.Validate(); err != nil { 619 return nil, err 620 } 621 622 kafkaTargets[k] = kafkaArgs 623 } 624 625 return kafkaTargets, nil 626 } 627 628 // DefaultMQTTKVS - default MQTT config 629 var ( 630 DefaultMQTTKVS = config.KVS{ 631 config.KV{ 632 Key: config.Enable, 633 Value: config.EnableOff, 634 }, 635 config.KV{ 636 Key: target.MqttBroker, 637 Value: "", 638 }, 639 config.KV{ 640 Key: target.MqttTopic, 641 Value: "", 642 }, 643 config.KV{ 644 Key: target.MqttPassword, 645 Value: "", 646 }, 647 config.KV{ 648 Key: target.MqttUsername, 649 Value: "", 650 }, 651 config.KV{ 652 Key: target.MqttQoS, 653 Value: "0", 654 }, 655 config.KV{ 656 Key: target.MqttKeepAliveInterval, 657 Value: "0s", 658 }, 659 config.KV{ 660 Key: target.MqttReconnectInterval, 661 Value: "0s", 662 }, 663 config.KV{ 664 Key: target.MqttQueueDir, 665 Value: "", 666 }, 667 config.KV{ 668 Key: target.MqttQueueLimit, 669 Value: "0", 670 }, 671 } 672 ) 673 674 // GetNotifyMQTT - returns a map of registered notification 'mqtt' targets 675 func GetNotifyMQTT(mqttKVS map[string]config.KVS, rootCAs *x509.CertPool) (map[string]target.MQTTArgs, error) { 676 mqttTargets := make(map[string]target.MQTTArgs) 677 for k, kv := range mergeTargets(mqttKVS, target.EnvMQTTEnable, DefaultMQTTKVS) { 678 enableEnv := target.EnvMQTTEnable 679 if k != config.Default { 680 enableEnv = enableEnv + config.Default + k 681 } 682 683 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 684 if err != nil { 685 return nil, err 686 } 687 if !enabled { 688 continue 689 } 690 691 brokerEnv := target.EnvMQTTBroker 692 if k != config.Default { 693 brokerEnv = brokerEnv + config.Default + k 694 } 695 696 brokerURL, err := xnet.ParseURL(env.Get(brokerEnv, kv.Get(target.MqttBroker))) 697 if err != nil { 698 return nil, err 699 } 700 701 reconnectIntervalEnv := target.EnvMQTTReconnectInterval 702 if k != config.Default { 703 reconnectIntervalEnv = reconnectIntervalEnv + config.Default + k 704 } 705 reconnectInterval, err := time.ParseDuration(env.Get(reconnectIntervalEnv, 706 kv.Get(target.MqttReconnectInterval))) 707 if err != nil { 708 return nil, err 709 } 710 711 keepAliveIntervalEnv := target.EnvMQTTKeepAliveInterval 712 if k != config.Default { 713 keepAliveIntervalEnv = keepAliveIntervalEnv + config.Default + k 714 } 715 keepAliveInterval, err := time.ParseDuration(env.Get(keepAliveIntervalEnv, 716 kv.Get(target.MqttKeepAliveInterval))) 717 if err != nil { 718 return nil, err 719 } 720 721 queueLimitEnv := target.EnvMQTTQueueLimit 722 if k != config.Default { 723 queueLimitEnv = queueLimitEnv + config.Default + k 724 } 725 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.MqttQueueLimit)), 10, 64) 726 if err != nil { 727 return nil, err 728 } 729 730 qosEnv := target.EnvMQTTQoS 731 if k != config.Default { 732 qosEnv = qosEnv + config.Default + k 733 } 734 735 // Parse uint8 value 736 qos, err := strconv.ParseUint(env.Get(qosEnv, kv.Get(target.MqttQoS)), 10, 8) 737 if err != nil { 738 return nil, err 739 } 740 741 topicEnv := target.EnvMQTTTopic 742 if k != config.Default { 743 topicEnv = topicEnv + config.Default + k 744 } 745 746 usernameEnv := target.EnvMQTTUsername 747 if k != config.Default { 748 usernameEnv = usernameEnv + config.Default + k 749 } 750 751 passwordEnv := target.EnvMQTTPassword 752 if k != config.Default { 753 passwordEnv = passwordEnv + config.Default + k 754 } 755 756 queueDirEnv := target.EnvMQTTQueueDir 757 if k != config.Default { 758 queueDirEnv = queueDirEnv + config.Default + k 759 } 760 761 mqttArgs := target.MQTTArgs{ 762 Enable: enabled, 763 Broker: *brokerURL, 764 Topic: env.Get(topicEnv, kv.Get(target.MqttTopic)), 765 QoS: byte(qos), 766 User: env.Get(usernameEnv, kv.Get(target.MqttUsername)), 767 Password: env.Get(passwordEnv, kv.Get(target.MqttPassword)), 768 MaxReconnectInterval: reconnectInterval, 769 KeepAlive: keepAliveInterval, 770 RootCAs: rootCAs, 771 QueueDir: env.Get(queueDirEnv, kv.Get(target.MqttQueueDir)), 772 QueueLimit: queueLimit, 773 } 774 775 if err = mqttArgs.Validate(); err != nil { 776 return nil, err 777 } 778 mqttTargets[k] = mqttArgs 779 } 780 return mqttTargets, nil 781 } 782 783 // DefaultMySQLKVS - default KV for MySQL 784 var ( 785 DefaultMySQLKVS = config.KVS{ 786 config.KV{ 787 Key: config.Enable, 788 Value: config.EnableOff, 789 }, 790 config.KV{ 791 Key: target.MySQLFormat, 792 Value: formatNamespace, 793 }, 794 config.KV{ 795 Key: target.MySQLDSNString, 796 Value: "", 797 }, 798 config.KV{ 799 Key: target.MySQLTable, 800 Value: "", 801 }, 802 config.KV{ 803 Key: target.MySQLQueueDir, 804 Value: "", 805 }, 806 config.KV{ 807 Key: target.MySQLQueueLimit, 808 Value: "0", 809 }, 810 config.KV{ 811 Key: target.MySQLMaxOpenConnections, 812 Value: "2", 813 }, 814 } 815 ) 816 817 // GetNotifyMySQL - returns a map of registered notification 'mysql' targets 818 func GetNotifyMySQL(mysqlKVS map[string]config.KVS) (map[string]target.MySQLArgs, error) { 819 mysqlTargets := make(map[string]target.MySQLArgs) 820 for k, kv := range mergeTargets(mysqlKVS, target.EnvMySQLEnable, DefaultMySQLKVS) { 821 enableEnv := target.EnvMySQLEnable 822 if k != config.Default { 823 enableEnv = enableEnv + config.Default + k 824 } 825 826 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 827 if err != nil { 828 return nil, err 829 } 830 if !enabled { 831 continue 832 } 833 834 queueLimitEnv := target.EnvMySQLQueueLimit 835 if k != config.Default { 836 queueLimitEnv = queueLimitEnv + config.Default + k 837 } 838 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.MySQLQueueLimit)), 10, 64) 839 if err != nil { 840 return nil, err 841 } 842 843 formatEnv := target.EnvMySQLFormat 844 if k != config.Default { 845 formatEnv = formatEnv + config.Default + k 846 } 847 848 dsnStringEnv := target.EnvMySQLDSNString 849 if k != config.Default { 850 dsnStringEnv = dsnStringEnv + config.Default + k 851 } 852 853 tableEnv := target.EnvMySQLTable 854 if k != config.Default { 855 tableEnv = tableEnv + config.Default + k 856 } 857 858 queueDirEnv := target.EnvMySQLQueueDir 859 if k != config.Default { 860 queueDirEnv = queueDirEnv + config.Default + k 861 } 862 863 maxOpenConnectionsEnv := target.EnvMySQLMaxOpenConnections 864 if k != config.Default { 865 maxOpenConnectionsEnv = maxOpenConnectionsEnv + config.Default + k 866 } 867 868 maxOpenConnections, cErr := strconv.Atoi(env.Get(maxOpenConnectionsEnv, kv.Get(target.MySQLMaxOpenConnections))) 869 if cErr != nil { 870 return nil, cErr 871 } 872 873 mysqlArgs := target.MySQLArgs{ 874 Enable: enabled, 875 Format: env.Get(formatEnv, kv.Get(target.MySQLFormat)), 876 DSN: env.Get(dsnStringEnv, kv.Get(target.MySQLDSNString)), 877 Table: env.Get(tableEnv, kv.Get(target.MySQLTable)), 878 QueueDir: env.Get(queueDirEnv, kv.Get(target.MySQLQueueDir)), 879 QueueLimit: queueLimit, 880 MaxOpenConnections: maxOpenConnections, 881 } 882 if err = mysqlArgs.Validate(); err != nil { 883 return nil, err 884 } 885 mysqlTargets[k] = mysqlArgs 886 } 887 return mysqlTargets, nil 888 } 889 890 // DefaultNATSKVS - NATS KV for nats config. 891 var ( 892 DefaultNATSKVS = config.KVS{ 893 config.KV{ 894 Key: config.Enable, 895 Value: config.EnableOff, 896 }, 897 config.KV{ 898 Key: target.NATSAddress, 899 Value: "", 900 }, 901 config.KV{ 902 Key: target.NATSSubject, 903 Value: "", 904 }, 905 config.KV{ 906 Key: target.NATSUsername, 907 Value: "", 908 }, 909 config.KV{ 910 Key: target.NATSPassword, 911 Value: "", 912 }, 913 config.KV{ 914 Key: target.NATSToken, 915 Value: "", 916 }, 917 config.KV{ 918 Key: target.NATSTLS, 919 Value: config.EnableOff, 920 }, 921 config.KV{ 922 Key: target.NATSTLSSkipVerify, 923 Value: config.EnableOff, 924 }, 925 config.KV{ 926 Key: target.NATSCertAuthority, 927 Value: "", 928 }, 929 config.KV{ 930 Key: target.NATSClientCert, 931 Value: "", 932 }, 933 config.KV{ 934 Key: target.NATSClientKey, 935 Value: "", 936 }, 937 config.KV{ 938 Key: target.NATSPingInterval, 939 Value: "0", 940 }, 941 config.KV{ 942 Key: target.NATSStreaming, 943 Value: config.EnableOff, 944 }, 945 config.KV{ 946 Key: target.NATSStreamingAsync, 947 Value: config.EnableOff, 948 }, 949 config.KV{ 950 Key: target.NATSStreamingMaxPubAcksInFlight, 951 Value: "0", 952 }, 953 config.KV{ 954 Key: target.NATSStreamingClusterID, 955 Value: "", 956 }, 957 config.KV{ 958 Key: target.NATSQueueDir, 959 Value: "", 960 }, 961 config.KV{ 962 Key: target.NATSQueueLimit, 963 Value: "0", 964 }, 965 } 966 ) 967 968 // GetNotifyNATS - returns a map of registered notification 'nats' targets 969 func GetNotifyNATS(natsKVS map[string]config.KVS, rootCAs *x509.CertPool) (map[string]target.NATSArgs, error) { 970 natsTargets := make(map[string]target.NATSArgs) 971 for k, kv := range mergeTargets(natsKVS, target.EnvNATSEnable, DefaultNATSKVS) { 972 enableEnv := target.EnvNATSEnable 973 if k != config.Default { 974 enableEnv = enableEnv + config.Default + k 975 } 976 977 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 978 if err != nil { 979 return nil, err 980 } 981 if !enabled { 982 continue 983 } 984 985 addressEnv := target.EnvNATSAddress 986 if k != config.Default { 987 addressEnv = addressEnv + config.Default + k 988 } 989 990 address, err := xnet.ParseHost(env.Get(addressEnv, kv.Get(target.NATSAddress))) 991 if err != nil { 992 return nil, err 993 } 994 995 pingIntervalEnv := target.EnvNATSPingInterval 996 if k != config.Default { 997 pingIntervalEnv = pingIntervalEnv + config.Default + k 998 } 999 1000 pingInterval, err := strconv.ParseInt(env.Get(pingIntervalEnv, kv.Get(target.NATSPingInterval)), 10, 64) 1001 if err != nil { 1002 return nil, err 1003 } 1004 1005 queueLimitEnv := target.EnvNATSQueueLimit 1006 if k != config.Default { 1007 queueLimitEnv = queueLimitEnv + config.Default + k 1008 } 1009 1010 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.NATSQueueLimit)), 10, 64) 1011 if err != nil { 1012 return nil, err 1013 } 1014 1015 tlsEnv := target.EnvNATSTLS 1016 if k != config.Default { 1017 tlsEnv = tlsEnv + config.Default + k 1018 } 1019 1020 tlsSkipVerifyEnv := target.EnvNATSTLSSkipVerify 1021 if k != config.Default { 1022 tlsSkipVerifyEnv = tlsSkipVerifyEnv + config.Default + k 1023 } 1024 1025 subjectEnv := target.EnvNATSSubject 1026 if k != config.Default { 1027 subjectEnv = subjectEnv + config.Default + k 1028 } 1029 1030 usernameEnv := target.EnvNATSUsername 1031 if k != config.Default { 1032 usernameEnv = usernameEnv + config.Default + k 1033 } 1034 1035 passwordEnv := target.EnvNATSPassword 1036 if k != config.Default { 1037 passwordEnv = passwordEnv + config.Default + k 1038 } 1039 1040 tokenEnv := target.EnvNATSToken 1041 if k != config.Default { 1042 tokenEnv = tokenEnv + config.Default + k 1043 } 1044 1045 queueDirEnv := target.EnvNATSQueueDir 1046 if k != config.Default { 1047 queueDirEnv = queueDirEnv + config.Default + k 1048 } 1049 1050 certAuthorityEnv := target.EnvNATSCertAuthority 1051 if k != config.Default { 1052 certAuthorityEnv = certAuthorityEnv + config.Default + k 1053 } 1054 1055 clientCertEnv := target.EnvNATSClientCert 1056 if k != config.Default { 1057 clientCertEnv = clientCertEnv + config.Default + k 1058 } 1059 1060 clientKeyEnv := target.EnvNATSClientKey 1061 if k != config.Default { 1062 clientKeyEnv = clientKeyEnv + config.Default + k 1063 } 1064 1065 natsArgs := target.NATSArgs{ 1066 Enable: true, 1067 Address: *address, 1068 Subject: env.Get(subjectEnv, kv.Get(target.NATSSubject)), 1069 Username: env.Get(usernameEnv, kv.Get(target.NATSUsername)), 1070 Password: env.Get(passwordEnv, kv.Get(target.NATSPassword)), 1071 CertAuthority: env.Get(certAuthorityEnv, kv.Get(target.NATSCertAuthority)), 1072 ClientCert: env.Get(clientCertEnv, kv.Get(target.NATSClientCert)), 1073 ClientKey: env.Get(clientKeyEnv, kv.Get(target.NATSClientKey)), 1074 Token: env.Get(tokenEnv, kv.Get(target.NATSToken)), 1075 TLS: env.Get(tlsEnv, kv.Get(target.NATSTLS)) == config.EnableOn, 1076 TLSSkipVerify: env.Get(tlsSkipVerifyEnv, kv.Get(target.NATSTLSSkipVerify)) == config.EnableOn, 1077 PingInterval: pingInterval, 1078 QueueDir: env.Get(queueDirEnv, kv.Get(target.NATSQueueDir)), 1079 QueueLimit: queueLimit, 1080 RootCAs: rootCAs, 1081 } 1082 1083 streamingEnableEnv := target.EnvNATSStreaming 1084 if k != config.Default { 1085 streamingEnableEnv = streamingEnableEnv + config.Default + k 1086 } 1087 1088 streamingEnabled := env.Get(streamingEnableEnv, kv.Get(target.NATSStreaming)) == config.EnableOn 1089 if streamingEnabled { 1090 asyncEnv := target.EnvNATSStreamingAsync 1091 if k != config.Default { 1092 asyncEnv = asyncEnv + config.Default + k 1093 } 1094 maxPubAcksInflightEnv := target.EnvNATSStreamingMaxPubAcksInFlight 1095 if k != config.Default { 1096 maxPubAcksInflightEnv = maxPubAcksInflightEnv + config.Default + k 1097 } 1098 maxPubAcksInflight, err := strconv.Atoi(env.Get(maxPubAcksInflightEnv, 1099 kv.Get(target.NATSStreamingMaxPubAcksInFlight))) 1100 if err != nil { 1101 return nil, err 1102 } 1103 clusterIDEnv := target.EnvNATSStreamingClusterID 1104 if k != config.Default { 1105 clusterIDEnv = clusterIDEnv + config.Default + k 1106 } 1107 natsArgs.Streaming.Enable = streamingEnabled 1108 natsArgs.Streaming.ClusterID = env.Get(clusterIDEnv, kv.Get(target.NATSStreamingClusterID)) 1109 natsArgs.Streaming.Async = env.Get(asyncEnv, kv.Get(target.NATSStreamingAsync)) == config.EnableOn 1110 natsArgs.Streaming.MaxPubAcksInflight = maxPubAcksInflight 1111 } 1112 1113 if err = natsArgs.Validate(); err != nil { 1114 return nil, err 1115 } 1116 1117 natsTargets[k] = natsArgs 1118 } 1119 return natsTargets, nil 1120 } 1121 1122 // DefaultNSQKVS - NSQ KV for config 1123 var ( 1124 DefaultNSQKVS = config.KVS{ 1125 config.KV{ 1126 Key: config.Enable, 1127 Value: config.EnableOff, 1128 }, 1129 config.KV{ 1130 Key: target.NSQAddress, 1131 Value: "", 1132 }, 1133 config.KV{ 1134 Key: target.NSQTopic, 1135 Value: "", 1136 }, 1137 config.KV{ 1138 Key: target.NSQTLS, 1139 Value: config.EnableOff, 1140 }, 1141 config.KV{ 1142 Key: target.NSQTLSSkipVerify, 1143 Value: config.EnableOff, 1144 }, 1145 config.KV{ 1146 Key: target.NSQQueueDir, 1147 Value: "", 1148 }, 1149 config.KV{ 1150 Key: target.NSQQueueLimit, 1151 Value: "0", 1152 }, 1153 } 1154 ) 1155 1156 // GetNotifyNSQ - returns a map of registered notification 'nsq' targets 1157 func GetNotifyNSQ(nsqKVS map[string]config.KVS) (map[string]target.NSQArgs, error) { 1158 nsqTargets := make(map[string]target.NSQArgs) 1159 for k, kv := range mergeTargets(nsqKVS, target.EnvNSQEnable, DefaultNSQKVS) { 1160 enableEnv := target.EnvNSQEnable 1161 if k != config.Default { 1162 enableEnv = enableEnv + config.Default + k 1163 } 1164 1165 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1166 if err != nil { 1167 return nil, err 1168 } 1169 if !enabled { 1170 continue 1171 } 1172 1173 addressEnv := target.EnvNSQAddress 1174 if k != config.Default { 1175 addressEnv = addressEnv + config.Default + k 1176 } 1177 nsqdAddress, err := xnet.ParseHost(env.Get(addressEnv, kv.Get(target.NSQAddress))) 1178 if err != nil { 1179 return nil, err 1180 } 1181 tlsEnableEnv := target.EnvNSQTLS 1182 if k != config.Default { 1183 tlsEnableEnv = tlsEnableEnv + config.Default + k 1184 } 1185 tlsSkipVerifyEnv := target.EnvNSQTLSSkipVerify 1186 if k != config.Default { 1187 tlsSkipVerifyEnv = tlsSkipVerifyEnv + config.Default + k 1188 } 1189 1190 queueLimitEnv := target.EnvNSQQueueLimit 1191 if k != config.Default { 1192 queueLimitEnv = queueLimitEnv + config.Default + k 1193 } 1194 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.NSQQueueLimit)), 10, 64) 1195 if err != nil { 1196 return nil, err 1197 } 1198 1199 topicEnv := target.EnvNSQTopic 1200 if k != config.Default { 1201 topicEnv = topicEnv + config.Default + k 1202 } 1203 queueDirEnv := target.EnvNSQQueueDir 1204 if k != config.Default { 1205 queueDirEnv = queueDirEnv + config.Default + k 1206 } 1207 1208 nsqArgs := target.NSQArgs{ 1209 Enable: enabled, 1210 NSQDAddress: *nsqdAddress, 1211 Topic: env.Get(topicEnv, kv.Get(target.NSQTopic)), 1212 QueueDir: env.Get(queueDirEnv, kv.Get(target.NSQQueueDir)), 1213 QueueLimit: queueLimit, 1214 } 1215 nsqArgs.TLS.Enable = env.Get(tlsEnableEnv, kv.Get(target.NSQTLS)) == config.EnableOn 1216 nsqArgs.TLS.SkipVerify = env.Get(tlsSkipVerifyEnv, kv.Get(target.NSQTLSSkipVerify)) == config.EnableOn 1217 1218 if err = nsqArgs.Validate(); err != nil { 1219 return nil, err 1220 } 1221 1222 nsqTargets[k] = nsqArgs 1223 } 1224 return nsqTargets, nil 1225 } 1226 1227 // DefaultPostgresKVS - default Postgres KV for server config. 1228 var ( 1229 DefaultPostgresKVS = config.KVS{ 1230 config.KV{ 1231 Key: config.Enable, 1232 Value: config.EnableOff, 1233 }, 1234 config.KV{ 1235 Key: target.PostgresFormat, 1236 Value: formatNamespace, 1237 }, 1238 config.KV{ 1239 Key: target.PostgresConnectionString, 1240 Value: "", 1241 }, 1242 config.KV{ 1243 Key: target.PostgresTable, 1244 Value: "", 1245 }, 1246 config.KV{ 1247 Key: target.PostgresQueueDir, 1248 Value: "", 1249 }, 1250 config.KV{ 1251 Key: target.PostgresQueueLimit, 1252 Value: "0", 1253 }, 1254 config.KV{ 1255 Key: target.PostgresMaxOpenConnections, 1256 Value: "2", 1257 }, 1258 } 1259 ) 1260 1261 // GetNotifyPostgres - returns a map of registered notification 'postgres' targets 1262 func GetNotifyPostgres(postgresKVS map[string]config.KVS) (map[string]target.PostgreSQLArgs, error) { 1263 psqlTargets := make(map[string]target.PostgreSQLArgs) 1264 for k, kv := range mergeTargets(postgresKVS, target.EnvPostgresEnable, DefaultPostgresKVS) { 1265 enableEnv := target.EnvPostgresEnable 1266 if k != config.Default { 1267 enableEnv = enableEnv + config.Default + k 1268 } 1269 1270 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1271 if err != nil { 1272 return nil, err 1273 } 1274 if !enabled { 1275 continue 1276 } 1277 1278 queueLimitEnv := target.EnvPostgresQueueLimit 1279 if k != config.Default { 1280 queueLimitEnv = queueLimitEnv + config.Default + k 1281 } 1282 1283 queueLimit, err := strconv.Atoi(env.Get(queueLimitEnv, kv.Get(target.PostgresQueueLimit))) 1284 if err != nil { 1285 return nil, err 1286 } 1287 1288 formatEnv := target.EnvPostgresFormat 1289 if k != config.Default { 1290 formatEnv = formatEnv + config.Default + k 1291 } 1292 1293 connectionStringEnv := target.EnvPostgresConnectionString 1294 if k != config.Default { 1295 connectionStringEnv = connectionStringEnv + config.Default + k 1296 } 1297 1298 tableEnv := target.EnvPostgresTable 1299 if k != config.Default { 1300 tableEnv = tableEnv + config.Default + k 1301 } 1302 1303 queueDirEnv := target.EnvPostgresQueueDir 1304 if k != config.Default { 1305 queueDirEnv = queueDirEnv + config.Default + k 1306 } 1307 1308 maxOpenConnectionsEnv := target.EnvPostgresMaxOpenConnections 1309 if k != config.Default { 1310 maxOpenConnectionsEnv = maxOpenConnectionsEnv + config.Default + k 1311 } 1312 1313 maxOpenConnections, cErr := strconv.Atoi(env.Get(maxOpenConnectionsEnv, kv.Get(target.PostgresMaxOpenConnections))) 1314 if cErr != nil { 1315 return nil, cErr 1316 } 1317 1318 psqlArgs := target.PostgreSQLArgs{ 1319 Enable: enabled, 1320 Format: env.Get(formatEnv, kv.Get(target.PostgresFormat)), 1321 ConnectionString: env.Get(connectionStringEnv, kv.Get(target.PostgresConnectionString)), 1322 Table: env.Get(tableEnv, kv.Get(target.PostgresTable)), 1323 QueueDir: env.Get(queueDirEnv, kv.Get(target.PostgresQueueDir)), 1324 QueueLimit: uint64(queueLimit), 1325 MaxOpenConnections: maxOpenConnections, 1326 } 1327 if err = psqlArgs.Validate(); err != nil { 1328 return nil, err 1329 } 1330 psqlTargets[k] = psqlArgs 1331 } 1332 1333 return psqlTargets, nil 1334 } 1335 1336 // DefaultRedisKVS - default KV for redis config 1337 var ( 1338 DefaultRedisKVS = config.KVS{ 1339 config.KV{ 1340 Key: config.Enable, 1341 Value: config.EnableOff, 1342 }, 1343 config.KV{ 1344 Key: target.RedisFormat, 1345 Value: formatNamespace, 1346 }, 1347 config.KV{ 1348 Key: target.RedisAddress, 1349 Value: "", 1350 }, 1351 config.KV{ 1352 Key: target.RedisKey, 1353 Value: "", 1354 }, 1355 config.KV{ 1356 Key: target.RedisPassword, 1357 Value: "", 1358 }, 1359 config.KV{ 1360 Key: target.RedisQueueDir, 1361 Value: "", 1362 }, 1363 config.KV{ 1364 Key: target.RedisQueueLimit, 1365 Value: "0", 1366 }, 1367 } 1368 ) 1369 1370 // GetNotifyRedis - returns a map of registered notification 'redis' targets 1371 func GetNotifyRedis(redisKVS map[string]config.KVS) (map[string]target.RedisArgs, error) { 1372 redisTargets := make(map[string]target.RedisArgs) 1373 for k, kv := range mergeTargets(redisKVS, target.EnvRedisEnable, DefaultRedisKVS) { 1374 enableEnv := target.EnvRedisEnable 1375 if k != config.Default { 1376 enableEnv = enableEnv + config.Default + k 1377 } 1378 1379 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1380 if err != nil { 1381 return nil, err 1382 } 1383 if !enabled { 1384 continue 1385 } 1386 1387 addressEnv := target.EnvRedisAddress 1388 if k != config.Default { 1389 addressEnv = addressEnv + config.Default + k 1390 } 1391 addr, err := xnet.ParseHost(env.Get(addressEnv, kv.Get(target.RedisAddress))) 1392 if err != nil { 1393 return nil, err 1394 } 1395 queueLimitEnv := target.EnvRedisQueueLimit 1396 if k != config.Default { 1397 queueLimitEnv = queueLimitEnv + config.Default + k 1398 } 1399 queueLimit, err := strconv.Atoi(env.Get(queueLimitEnv, kv.Get(target.RedisQueueLimit))) 1400 if err != nil { 1401 return nil, err 1402 } 1403 formatEnv := target.EnvRedisFormat 1404 if k != config.Default { 1405 formatEnv = formatEnv + config.Default + k 1406 } 1407 passwordEnv := target.EnvRedisPassword 1408 if k != config.Default { 1409 passwordEnv = passwordEnv + config.Default + k 1410 } 1411 keyEnv := target.EnvRedisKey 1412 if k != config.Default { 1413 keyEnv = keyEnv + config.Default + k 1414 } 1415 queueDirEnv := target.EnvRedisQueueDir 1416 if k != config.Default { 1417 queueDirEnv = queueDirEnv + config.Default + k 1418 } 1419 redisArgs := target.RedisArgs{ 1420 Enable: enabled, 1421 Format: env.Get(formatEnv, kv.Get(target.RedisFormat)), 1422 Addr: *addr, 1423 Password: env.Get(passwordEnv, kv.Get(target.RedisPassword)), 1424 Key: env.Get(keyEnv, kv.Get(target.RedisKey)), 1425 QueueDir: env.Get(queueDirEnv, kv.Get(target.RedisQueueDir)), 1426 QueueLimit: uint64(queueLimit), 1427 } 1428 if err = redisArgs.Validate(); err != nil { 1429 return nil, err 1430 } 1431 redisTargets[k] = redisArgs 1432 } 1433 return redisTargets, nil 1434 } 1435 1436 // DefaultWebhookKVS - default KV for webhook config 1437 var ( 1438 DefaultWebhookKVS = config.KVS{ 1439 config.KV{ 1440 Key: config.Enable, 1441 Value: config.EnableOff, 1442 }, 1443 config.KV{ 1444 Key: target.WebhookEndpoint, 1445 Value: "", 1446 }, 1447 config.KV{ 1448 Key: target.WebhookAuthToken, 1449 Value: "", 1450 }, 1451 config.KV{ 1452 Key: target.WebhookQueueLimit, 1453 Value: "0", 1454 }, 1455 config.KV{ 1456 Key: target.WebhookQueueDir, 1457 Value: "", 1458 }, 1459 config.KV{ 1460 Key: target.WebhookClientCert, 1461 Value: "", 1462 }, 1463 config.KV{ 1464 Key: target.WebhookClientKey, 1465 Value: "", 1466 }, 1467 } 1468 ) 1469 1470 // GetNotifyWebhook - returns a map of registered notification 'webhook' targets 1471 func GetNotifyWebhook(webhookKVS map[string]config.KVS, transport *http.Transport) ( 1472 map[string]target.WebhookArgs, error) { 1473 webhookTargets := make(map[string]target.WebhookArgs) 1474 for k, kv := range mergeTargets(webhookKVS, target.EnvWebhookEnable, DefaultWebhookKVS) { 1475 enableEnv := target.EnvWebhookEnable 1476 if k != config.Default { 1477 enableEnv = enableEnv + config.Default + k 1478 } 1479 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1480 if err != nil { 1481 return nil, err 1482 } 1483 if !enabled { 1484 continue 1485 } 1486 urlEnv := target.EnvWebhookEndpoint 1487 if k != config.Default { 1488 urlEnv = urlEnv + config.Default + k 1489 } 1490 url, err := xnet.ParseHTTPURL(env.Get(urlEnv, kv.Get(target.WebhookEndpoint))) 1491 if err != nil { 1492 return nil, err 1493 } 1494 queueLimitEnv := target.EnvWebhookQueueLimit 1495 if k != config.Default { 1496 queueLimitEnv = queueLimitEnv + config.Default + k 1497 } 1498 queueLimit, err := strconv.Atoi(env.Get(queueLimitEnv, kv.Get(target.WebhookQueueLimit))) 1499 if err != nil { 1500 return nil, err 1501 } 1502 queueDirEnv := target.EnvWebhookQueueDir 1503 if k != config.Default { 1504 queueDirEnv = queueDirEnv + config.Default + k 1505 } 1506 authEnv := target.EnvWebhookAuthToken 1507 if k != config.Default { 1508 authEnv = authEnv + config.Default + k 1509 } 1510 clientCertEnv := target.EnvWebhookClientCert 1511 if k != config.Default { 1512 clientCertEnv = clientCertEnv + config.Default + k 1513 } 1514 1515 clientKeyEnv := target.EnvWebhookClientKey 1516 if k != config.Default { 1517 clientKeyEnv = clientKeyEnv + config.Default + k 1518 } 1519 1520 webhookArgs := target.WebhookArgs{ 1521 Enable: enabled, 1522 Endpoint: *url, 1523 Transport: transport, 1524 AuthToken: env.Get(authEnv, kv.Get(target.WebhookAuthToken)), 1525 QueueDir: env.Get(queueDirEnv, kv.Get(target.WebhookQueueDir)), 1526 QueueLimit: uint64(queueLimit), 1527 ClientCert: env.Get(clientCertEnv, kv.Get(target.WebhookClientCert)), 1528 ClientKey: env.Get(clientKeyEnv, kv.Get(target.WebhookClientKey)), 1529 } 1530 if err = webhookArgs.Validate(); err != nil { 1531 return nil, err 1532 } 1533 webhookTargets[k] = webhookArgs 1534 } 1535 return webhookTargets, nil 1536 } 1537 1538 // DefaultESKVS - default KV config for Elasticsearch target 1539 var ( 1540 DefaultESKVS = config.KVS{ 1541 config.KV{ 1542 Key: config.Enable, 1543 Value: config.EnableOff, 1544 }, 1545 config.KV{ 1546 Key: target.ElasticURL, 1547 Value: "", 1548 }, 1549 config.KV{ 1550 Key: target.ElasticFormat, 1551 Value: formatNamespace, 1552 }, 1553 config.KV{ 1554 Key: target.ElasticIndex, 1555 Value: "", 1556 }, 1557 config.KV{ 1558 Key: target.ElasticQueueDir, 1559 Value: "", 1560 }, 1561 config.KV{ 1562 Key: target.ElasticQueueLimit, 1563 Value: "0", 1564 }, 1565 config.KV{ 1566 Key: target.ElasticUsername, 1567 Value: "", 1568 }, 1569 config.KV{ 1570 Key: target.ElasticPassword, 1571 Value: "", 1572 }, 1573 } 1574 ) 1575 1576 // GetNotifyES - returns a map of registered notification 'elasticsearch' targets 1577 func GetNotifyES(esKVS map[string]config.KVS, transport *http.Transport) (map[string]target.ElasticsearchArgs, error) { 1578 esTargets := make(map[string]target.ElasticsearchArgs) 1579 for k, kv := range mergeTargets(esKVS, target.EnvElasticEnable, DefaultESKVS) { 1580 enableEnv := target.EnvElasticEnable 1581 if k != config.Default { 1582 enableEnv = enableEnv + config.Default + k 1583 } 1584 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1585 if err != nil { 1586 return nil, err 1587 } 1588 if !enabled { 1589 continue 1590 } 1591 1592 urlEnv := target.EnvElasticURL 1593 if k != config.Default { 1594 urlEnv = urlEnv + config.Default + k 1595 } 1596 1597 url, err := xnet.ParseHTTPURL(env.Get(urlEnv, kv.Get(target.ElasticURL))) 1598 if err != nil { 1599 return nil, err 1600 } 1601 1602 queueLimitEnv := target.EnvElasticQueueLimit 1603 if k != config.Default { 1604 queueLimitEnv = queueLimitEnv + config.Default + k 1605 } 1606 1607 queueLimit, err := strconv.Atoi(env.Get(queueLimitEnv, kv.Get(target.ElasticQueueLimit))) 1608 if err != nil { 1609 return nil, err 1610 } 1611 1612 formatEnv := target.EnvElasticFormat 1613 if k != config.Default { 1614 formatEnv = formatEnv + config.Default + k 1615 } 1616 1617 indexEnv := target.EnvElasticIndex 1618 if k != config.Default { 1619 indexEnv = indexEnv + config.Default + k 1620 } 1621 1622 queueDirEnv := target.EnvElasticQueueDir 1623 if k != config.Default { 1624 queueDirEnv = queueDirEnv + config.Default + k 1625 } 1626 1627 usernameEnv := target.EnvElasticUsername 1628 if k != config.Default { 1629 usernameEnv = usernameEnv + config.Default + k 1630 } 1631 1632 passwordEnv := target.EnvElasticPassword 1633 if k != config.Default { 1634 passwordEnv = passwordEnv + config.Default + k 1635 } 1636 1637 esArgs := target.ElasticsearchArgs{ 1638 Enable: enabled, 1639 Format: env.Get(formatEnv, kv.Get(target.ElasticFormat)), 1640 URL: *url, 1641 Index: env.Get(indexEnv, kv.Get(target.ElasticIndex)), 1642 QueueDir: env.Get(queueDirEnv, kv.Get(target.ElasticQueueDir)), 1643 QueueLimit: uint64(queueLimit), 1644 Transport: transport, 1645 Username: env.Get(usernameEnv, kv.Get(target.ElasticUsername)), 1646 Password: env.Get(passwordEnv, kv.Get(target.ElasticPassword)), 1647 } 1648 if err = esArgs.Validate(); err != nil { 1649 return nil, err 1650 } 1651 esTargets[k] = esArgs 1652 } 1653 return esTargets, nil 1654 } 1655 1656 // DefaultAMQPKVS - default KV for AMQP config 1657 var ( 1658 DefaultAMQPKVS = config.KVS{ 1659 config.KV{ 1660 Key: config.Enable, 1661 Value: config.EnableOff, 1662 }, 1663 config.KV{ 1664 Key: target.AmqpURL, 1665 Value: "", 1666 }, 1667 config.KV{ 1668 Key: target.AmqpExchange, 1669 Value: "", 1670 }, 1671 config.KV{ 1672 Key: target.AmqpExchangeType, 1673 Value: "", 1674 }, 1675 config.KV{ 1676 Key: target.AmqpRoutingKey, 1677 Value: "", 1678 }, 1679 config.KV{ 1680 Key: target.AmqpMandatory, 1681 Value: config.EnableOff, 1682 }, 1683 config.KV{ 1684 Key: target.AmqpDurable, 1685 Value: config.EnableOff, 1686 }, 1687 config.KV{ 1688 Key: target.AmqpNoWait, 1689 Value: config.EnableOff, 1690 }, 1691 config.KV{ 1692 Key: target.AmqpInternal, 1693 Value: config.EnableOff, 1694 }, 1695 config.KV{ 1696 Key: target.AmqpAutoDeleted, 1697 Value: config.EnableOff, 1698 }, 1699 config.KV{ 1700 Key: target.AmqpDeliveryMode, 1701 Value: "0", 1702 }, 1703 config.KV{ 1704 Key: target.AmqpQueueLimit, 1705 Value: "0", 1706 }, 1707 config.KV{ 1708 Key: target.AmqpQueueDir, 1709 Value: "", 1710 }, 1711 } 1712 ) 1713 1714 // GetNotifyAMQP - returns a map of registered notification 'amqp' targets 1715 func GetNotifyAMQP(amqpKVS map[string]config.KVS) (map[string]target.AMQPArgs, error) { 1716 amqpTargets := make(map[string]target.AMQPArgs) 1717 for k, kv := range mergeTargets(amqpKVS, target.EnvAMQPEnable, DefaultAMQPKVS) { 1718 enableEnv := target.EnvAMQPEnable 1719 if k != config.Default { 1720 enableEnv = enableEnv + config.Default + k 1721 } 1722 enabled, err := config.ParseBool(env.Get(enableEnv, kv.Get(config.Enable))) 1723 if err != nil { 1724 return nil, err 1725 } 1726 if !enabled { 1727 continue 1728 } 1729 urlEnv := target.EnvAMQPURL 1730 if k != config.Default { 1731 urlEnv = urlEnv + config.Default + k 1732 } 1733 url, err := xnet.ParseURL(env.Get(urlEnv, kv.Get(target.AmqpURL))) 1734 if err != nil { 1735 return nil, err 1736 } 1737 deliveryModeEnv := target.EnvAMQPDeliveryMode 1738 if k != config.Default { 1739 deliveryModeEnv = deliveryModeEnv + config.Default + k 1740 } 1741 deliveryMode, err := strconv.Atoi(env.Get(deliveryModeEnv, kv.Get(target.AmqpDeliveryMode))) 1742 if err != nil { 1743 return nil, err 1744 } 1745 exchangeEnv := target.EnvAMQPExchange 1746 if k != config.Default { 1747 exchangeEnv = exchangeEnv + config.Default + k 1748 } 1749 routingKeyEnv := target.EnvAMQPRoutingKey 1750 if k != config.Default { 1751 routingKeyEnv = routingKeyEnv + config.Default + k 1752 } 1753 exchangeTypeEnv := target.EnvAMQPExchangeType 1754 if k != config.Default { 1755 exchangeTypeEnv = exchangeTypeEnv + config.Default + k 1756 } 1757 mandatoryEnv := target.EnvAMQPMandatory 1758 if k != config.Default { 1759 mandatoryEnv = mandatoryEnv + config.Default + k 1760 } 1761 immediateEnv := target.EnvAMQPImmediate 1762 if k != config.Default { 1763 immediateEnv = immediateEnv + config.Default + k 1764 } 1765 durableEnv := target.EnvAMQPDurable 1766 if k != config.Default { 1767 durableEnv = durableEnv + config.Default + k 1768 } 1769 internalEnv := target.EnvAMQPInternal 1770 if k != config.Default { 1771 internalEnv = internalEnv + config.Default + k 1772 } 1773 noWaitEnv := target.EnvAMQPNoWait 1774 if k != config.Default { 1775 noWaitEnv = noWaitEnv + config.Default + k 1776 } 1777 autoDeletedEnv := target.EnvAMQPAutoDeleted 1778 if k != config.Default { 1779 autoDeletedEnv = autoDeletedEnv + config.Default + k 1780 } 1781 queueDirEnv := target.EnvAMQPQueueDir 1782 if k != config.Default { 1783 queueDirEnv = queueDirEnv + config.Default + k 1784 } 1785 queueLimitEnv := target.EnvAMQPQueueLimit 1786 if k != config.Default { 1787 queueLimitEnv = queueLimitEnv + config.Default + k 1788 } 1789 queueLimit, err := strconv.ParseUint(env.Get(queueLimitEnv, kv.Get(target.AmqpQueueLimit)), 10, 64) 1790 if err != nil { 1791 return nil, err 1792 } 1793 amqpArgs := target.AMQPArgs{ 1794 Enable: enabled, 1795 URL: *url, 1796 Exchange: env.Get(exchangeEnv, kv.Get(target.AmqpExchange)), 1797 RoutingKey: env.Get(routingKeyEnv, kv.Get(target.AmqpRoutingKey)), 1798 ExchangeType: env.Get(exchangeTypeEnv, kv.Get(target.AmqpExchangeType)), 1799 DeliveryMode: uint8(deliveryMode), 1800 Mandatory: env.Get(mandatoryEnv, kv.Get(target.AmqpMandatory)) == config.EnableOn, 1801 Immediate: env.Get(immediateEnv, kv.Get(target.AmqpImmediate)) == config.EnableOn, 1802 Durable: env.Get(durableEnv, kv.Get(target.AmqpDurable)) == config.EnableOn, 1803 Internal: env.Get(internalEnv, kv.Get(target.AmqpInternal)) == config.EnableOn, 1804 NoWait: env.Get(noWaitEnv, kv.Get(target.AmqpNoWait)) == config.EnableOn, 1805 AutoDeleted: env.Get(autoDeletedEnv, kv.Get(target.AmqpAutoDeleted)) == config.EnableOn, 1806 QueueDir: env.Get(queueDirEnv, kv.Get(target.AmqpQueueDir)), 1807 QueueLimit: queueLimit, 1808 } 1809 if err = amqpArgs.Validate(); err != nil { 1810 return nil, err 1811 } 1812 amqpTargets[k] = amqpArgs 1813 } 1814 return amqpTargets, nil 1815 }