github.imxd.top/hashicorp/consul@v1.4.5/agent/config/runtime_test.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "crypto/tls" 6 "encoding/base64" 7 "encoding/json" 8 "errors" 9 "flag" 10 "fmt" 11 "io/ioutil" 12 "net" 13 "os" 14 "path/filepath" 15 "reflect" 16 "strconv" 17 "strings" 18 "testing" 19 "time" 20 21 "github.com/hashicorp/consul/agent/structs" 22 "github.com/hashicorp/consul/lib" 23 "github.com/hashicorp/consul/testutil" 24 "github.com/hashicorp/consul/types" 25 "github.com/pascaldekloe/goe/verify" 26 "github.com/stretchr/testify/require" 27 ) 28 29 type configTest struct { 30 desc string 31 args []string 32 pre, post func() 33 json, jsontail []string 34 hcl, hcltail []string 35 skipformat bool 36 privatev4 func() ([]*net.IPAddr, error) 37 publicv6 func() ([]*net.IPAddr, error) 38 patch func(rt *RuntimeConfig) 39 err string 40 warns []string 41 hostname func() (string, error) 42 } 43 44 // TestConfigFlagsAndEdgecases tests the command line flags and 45 // edgecases for the config parsing. It provides a test structure which 46 // checks for warnings on deprecated fields and flags. These tests 47 // should check one option at a time if possible and should use generic 48 // values, e.g. 'a' or 1 instead of 'servicex' or 3306. 49 50 func TestConfigFlagsAndEdgecases(t *testing.T) { 51 dataDir := testutil.TempDir(t, "consul") 52 defer os.RemoveAll(dataDir) 53 54 tests := []configTest{ 55 // ------------------------------------------------------------ 56 // cmd line flags 57 // 58 59 { 60 desc: "-advertise", 61 args: []string{ 62 `-advertise=1.2.3.4`, 63 `-data-dir=` + dataDir, 64 }, 65 patch: func(rt *RuntimeConfig) { 66 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 67 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 68 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:8300") 69 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:8301") 70 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 71 rt.TaggedAddresses = map[string]string{ 72 "lan": "1.2.3.4", 73 "wan": "1.2.3.4", 74 } 75 rt.DataDir = dataDir 76 }, 77 }, 78 { 79 desc: "-advertise-wan", 80 args: []string{ 81 `-advertise-wan=1.2.3.4`, 82 `-data-dir=` + dataDir, 83 }, 84 patch: func(rt *RuntimeConfig) { 85 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 86 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 87 rt.TaggedAddresses = map[string]string{ 88 "lan": "10.0.0.1", 89 "wan": "1.2.3.4", 90 } 91 rt.DataDir = dataDir 92 }, 93 }, 94 { 95 desc: "-advertise and -advertise-wan", 96 args: []string{ 97 `-advertise=1.2.3.4`, 98 `-advertise-wan=5.6.7.8`, 99 `-data-dir=` + dataDir, 100 }, 101 patch: func(rt *RuntimeConfig) { 102 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 103 rt.AdvertiseAddrWAN = ipAddr("5.6.7.8") 104 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:8300") 105 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:8301") 106 rt.SerfAdvertiseAddrWAN = tcpAddr("5.6.7.8:8302") 107 rt.TaggedAddresses = map[string]string{ 108 "lan": "1.2.3.4", 109 "wan": "5.6.7.8", 110 } 111 rt.DataDir = dataDir 112 }, 113 }, 114 { 115 desc: "-bind", 116 args: []string{ 117 `-bind=1.2.3.4`, 118 `-data-dir=` + dataDir, 119 }, 120 patch: func(rt *RuntimeConfig) { 121 rt.BindAddr = ipAddr("1.2.3.4") 122 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 123 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 124 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:8300") 125 rt.RPCBindAddr = tcpAddr("1.2.3.4:8300") 126 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:8301") 127 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 128 rt.SerfBindAddrLAN = tcpAddr("1.2.3.4:8301") 129 rt.SerfBindAddrWAN = tcpAddr("1.2.3.4:8302") 130 rt.TaggedAddresses = map[string]string{ 131 "lan": "1.2.3.4", 132 "wan": "1.2.3.4", 133 } 134 rt.DataDir = dataDir 135 }, 136 }, 137 { 138 desc: "-bootstrap", 139 args: []string{ 140 `-bootstrap`, 141 `-server`, 142 `-data-dir=` + dataDir, 143 }, 144 patch: func(rt *RuntimeConfig) { 145 rt.Bootstrap = true 146 rt.ServerMode = true 147 rt.LeaveOnTerm = false 148 rt.SkipLeaveOnInt = true 149 rt.DataDir = dataDir 150 }, 151 warns: []string{"bootstrap = true: do not enable unless necessary"}, 152 }, 153 { 154 desc: "-bootstrap-expect", 155 args: []string{ 156 `-bootstrap-expect=3`, 157 `-server`, 158 `-data-dir=` + dataDir, 159 }, 160 patch: func(rt *RuntimeConfig) { 161 rt.BootstrapExpect = 3 162 rt.ServerMode = true 163 rt.LeaveOnTerm = false 164 rt.SkipLeaveOnInt = true 165 rt.DataDir = dataDir 166 }, 167 warns: []string{"bootstrap_expect > 0: expecting 3 servers"}, 168 }, 169 { 170 desc: "-client", 171 args: []string{ 172 `-client=1.2.3.4`, 173 `-data-dir=` + dataDir, 174 }, 175 patch: func(rt *RuntimeConfig) { 176 rt.ClientAddrs = []*net.IPAddr{ipAddr("1.2.3.4")} 177 rt.DNSAddrs = []net.Addr{tcpAddr("1.2.3.4:8600"), udpAddr("1.2.3.4:8600")} 178 rt.HTTPAddrs = []net.Addr{tcpAddr("1.2.3.4:8500")} 179 rt.DataDir = dataDir 180 }, 181 }, 182 { 183 desc: "-config-dir", 184 args: []string{ 185 `-data-dir=` + dataDir, 186 `-config-dir`, filepath.Join(dataDir, "conf.d"), 187 }, 188 patch: func(rt *RuntimeConfig) { 189 rt.Datacenter = "a" 190 rt.DataDir = dataDir 191 }, 192 pre: func() { 193 writeFile(filepath.Join(dataDir, "conf.d/conf.json"), []byte(`{"datacenter":"a"}`)) 194 }, 195 }, 196 { 197 desc: "-config-file json", 198 args: []string{ 199 `-data-dir=` + dataDir, 200 `-config-file`, filepath.Join(dataDir, "conf.json"), 201 }, 202 patch: func(rt *RuntimeConfig) { 203 rt.Datacenter = "a" 204 rt.DataDir = dataDir 205 }, 206 pre: func() { 207 writeFile(filepath.Join(dataDir, "conf.json"), []byte(`{"datacenter":"a"}`)) 208 }, 209 }, 210 { 211 desc: "-config-file hcl and json", 212 args: []string{ 213 `-data-dir=` + dataDir, 214 `-config-file`, filepath.Join(dataDir, "conf.hcl"), 215 `-config-file`, filepath.Join(dataDir, "conf.json"), 216 }, 217 patch: func(rt *RuntimeConfig) { 218 rt.Datacenter = "b" 219 rt.DataDir = dataDir 220 }, 221 pre: func() { 222 writeFile(filepath.Join(dataDir, "conf.hcl"), []byte(`datacenter = "a"`)) 223 writeFile(filepath.Join(dataDir, "conf.json"), []byte(`{"datacenter":"b"}`)) 224 }, 225 }, 226 { 227 desc: "-data-dir empty", 228 args: []string{ 229 `-data-dir=`, 230 }, 231 err: "data_dir cannot be empty", 232 }, 233 { 234 desc: "-data-dir non-directory", 235 args: []string{ 236 `-data-dir=runtime_test.go`, 237 }, 238 err: `data_dir "runtime_test.go" is not a directory`, 239 }, 240 { 241 desc: "-datacenter", 242 args: []string{ 243 `-datacenter=a`, 244 `-data-dir=` + dataDir, 245 }, 246 patch: func(rt *RuntimeConfig) { 247 rt.Datacenter = "a" 248 rt.DataDir = dataDir 249 }, 250 }, 251 { 252 desc: "-datacenter empty", 253 args: []string{ 254 `-datacenter=`, 255 `-data-dir=` + dataDir, 256 }, 257 err: "datacenter cannot be empty", 258 }, 259 { 260 desc: "-dev", 261 args: []string{ 262 `-dev`, 263 }, 264 patch: func(rt *RuntimeConfig) { 265 rt.AdvertiseAddrLAN = ipAddr("127.0.0.1") 266 rt.AdvertiseAddrWAN = ipAddr("127.0.0.1") 267 rt.BindAddr = ipAddr("127.0.0.1") 268 rt.ConnectEnabled = true 269 rt.DevMode = true 270 rt.DisableAnonymousSignature = true 271 rt.DisableKeyringFile = true 272 rt.EnableDebug = true 273 rt.EnableUI = true 274 rt.LeaveOnTerm = false 275 rt.LogLevel = "DEBUG" 276 rt.RPCAdvertiseAddr = tcpAddr("127.0.0.1:8300") 277 rt.RPCBindAddr = tcpAddr("127.0.0.1:8300") 278 rt.SerfAdvertiseAddrLAN = tcpAddr("127.0.0.1:8301") 279 rt.SerfAdvertiseAddrWAN = tcpAddr("127.0.0.1:8302") 280 rt.SerfBindAddrLAN = tcpAddr("127.0.0.1:8301") 281 rt.SerfBindAddrWAN = tcpAddr("127.0.0.1:8302") 282 rt.ServerMode = true 283 rt.SkipLeaveOnInt = true 284 rt.TaggedAddresses = map[string]string{"lan": "127.0.0.1", "wan": "127.0.0.1"} 285 rt.ConsulCoordinateUpdatePeriod = 100 * time.Millisecond 286 rt.ConsulRaftElectionTimeout = 52 * time.Millisecond 287 rt.ConsulRaftHeartbeatTimeout = 35 * time.Millisecond 288 rt.ConsulRaftLeaderLeaseTimeout = 20 * time.Millisecond 289 rt.GossipLANGossipInterval = 100 * time.Millisecond 290 rt.GossipLANProbeInterval = 100 * time.Millisecond 291 rt.GossipLANProbeTimeout = 100 * time.Millisecond 292 rt.GossipLANSuspicionMult = 3 293 rt.GossipWANGossipInterval = 100 * time.Millisecond 294 rt.GossipWANProbeInterval = 100 * time.Millisecond 295 rt.GossipWANProbeTimeout = 100 * time.Millisecond 296 rt.GossipWANSuspicionMult = 3 297 rt.ConsulServerHealthInterval = 10 * time.Millisecond 298 rt.GRPCPort = 8502 299 rt.GRPCAddrs = []net.Addr{tcpAddr("127.0.0.1:8502")} 300 }, 301 }, 302 { 303 desc: "-disable-host-node-id", 304 args: []string{ 305 `-disable-host-node-id`, 306 `-data-dir=` + dataDir, 307 }, 308 patch: func(rt *RuntimeConfig) { 309 rt.DisableHostNodeID = true 310 rt.DataDir = dataDir 311 }, 312 }, 313 { 314 desc: "-disable-keyring-file", 315 args: []string{ 316 `-disable-keyring-file`, 317 `-data-dir=` + dataDir, 318 }, 319 patch: func(rt *RuntimeConfig) { 320 rt.DisableKeyringFile = true 321 rt.DataDir = dataDir 322 }, 323 }, 324 { 325 desc: "-dns-port", 326 args: []string{ 327 `-dns-port=123`, 328 `-data-dir=` + dataDir, 329 }, 330 patch: func(rt *RuntimeConfig) { 331 rt.DNSPort = 123 332 rt.DNSAddrs = []net.Addr{tcpAddr("127.0.0.1:123"), udpAddr("127.0.0.1:123")} 333 rt.DataDir = dataDir 334 }, 335 }, 336 { 337 desc: "-domain", 338 args: []string{ 339 `-domain=a`, 340 `-data-dir=` + dataDir, 341 }, 342 patch: func(rt *RuntimeConfig) { 343 rt.DNSDomain = "a" 344 rt.DataDir = dataDir 345 }, 346 }, 347 { 348 desc: "-enable-script-checks", 349 args: []string{ 350 `-enable-script-checks`, 351 `-data-dir=` + dataDir, 352 }, 353 patch: func(rt *RuntimeConfig) { 354 rt.EnableLocalScriptChecks = true 355 rt.EnableRemoteScriptChecks = true 356 rt.DataDir = dataDir 357 }, 358 }, 359 { 360 desc: "-encrypt", 361 args: []string{ 362 `-encrypt=i0P+gFTkLPg0h53eNYjydg==`, 363 `-data-dir=` + dataDir, 364 }, 365 patch: func(rt *RuntimeConfig) { 366 rt.EncryptKey = "i0P+gFTkLPg0h53eNYjydg==" 367 rt.DataDir = dataDir 368 }, 369 }, 370 { 371 desc: "-config-format disabled, skip unknown files", 372 args: []string{ 373 `-data-dir=` + dataDir, 374 `-config-dir`, filepath.Join(dataDir, "conf"), 375 }, 376 patch: func(rt *RuntimeConfig) { 377 rt.Datacenter = "a" 378 rt.DataDir = dataDir 379 }, 380 pre: func() { 381 writeFile(filepath.Join(dataDir, "conf", "valid.json"), []byte(`{"datacenter":"a"}`)) 382 writeFile(filepath.Join(dataDir, "conf", "invalid.skip"), []byte(`NOPE`)) 383 }, 384 }, 385 { 386 desc: "-config-format=json", 387 args: []string{ 388 `-data-dir=` + dataDir, 389 `-config-format=json`, 390 `-config-file`, filepath.Join(dataDir, "conf"), 391 }, 392 patch: func(rt *RuntimeConfig) { 393 rt.Datacenter = "a" 394 rt.DataDir = dataDir 395 }, 396 pre: func() { 397 writeFile(filepath.Join(dataDir, "conf"), []byte(`{"datacenter":"a"}`)) 398 }, 399 }, 400 { 401 desc: "-config-format=hcl", 402 args: []string{ 403 `-data-dir=` + dataDir, 404 `-config-format=hcl`, 405 `-config-file`, filepath.Join(dataDir, "conf"), 406 }, 407 patch: func(rt *RuntimeConfig) { 408 rt.Datacenter = "a" 409 rt.DataDir = dataDir 410 }, 411 pre: func() { 412 writeFile(filepath.Join(dataDir, "conf"), []byte(`datacenter = "a"`)) 413 }, 414 }, 415 { 416 desc: "-config-format invalid", 417 args: []string{ 418 `-config-format=foobar`, 419 }, 420 err: "-config-format must be either 'hcl' or 'json'", 421 }, 422 { 423 desc: "-http-port", 424 args: []string{ 425 `-http-port=123`, 426 `-data-dir=` + dataDir, 427 }, 428 patch: func(rt *RuntimeConfig) { 429 rt.HTTPPort = 123 430 rt.HTTPAddrs = []net.Addr{tcpAddr("127.0.0.1:123")} 431 rt.DataDir = dataDir 432 }, 433 }, 434 { 435 desc: "-join", 436 args: []string{ 437 `-join=a`, 438 `-join=b`, 439 `-data-dir=` + dataDir, 440 }, 441 patch: func(rt *RuntimeConfig) { 442 rt.StartJoinAddrsLAN = []string{"a", "b"} 443 rt.DataDir = dataDir 444 }, 445 }, 446 { 447 desc: "-join-wan", 448 args: []string{ 449 `-join-wan=a`, 450 `-join-wan=b`, 451 `-data-dir=` + dataDir, 452 }, 453 patch: func(rt *RuntimeConfig) { 454 rt.StartJoinAddrsWAN = []string{"a", "b"} 455 rt.DataDir = dataDir 456 }, 457 }, 458 { 459 desc: "-log-level", 460 args: []string{ 461 `-log-level=a`, 462 `-data-dir=` + dataDir, 463 }, 464 patch: func(rt *RuntimeConfig) { 465 rt.LogLevel = "a" 466 rt.DataDir = dataDir 467 }, 468 }, 469 { 470 desc: "-node", 471 args: []string{ 472 `-node=a`, 473 `-data-dir=` + dataDir, 474 }, 475 patch: func(rt *RuntimeConfig) { 476 rt.NodeName = "a" 477 rt.DataDir = dataDir 478 }, 479 }, 480 { 481 desc: "-node-id", 482 args: []string{ 483 `-node-id=a`, 484 `-data-dir=` + dataDir, 485 }, 486 patch: func(rt *RuntimeConfig) { 487 rt.NodeID = "a" 488 rt.DataDir = dataDir 489 }, 490 }, 491 { 492 desc: "-node-meta", 493 args: []string{ 494 `-node-meta=a:b`, 495 `-node-meta=c:d`, 496 `-data-dir=` + dataDir, 497 }, 498 patch: func(rt *RuntimeConfig) { 499 rt.NodeMeta = map[string]string{"a": "b", "c": "d"} 500 rt.DataDir = dataDir 501 }, 502 }, 503 { 504 desc: "-non-voting-server", 505 args: []string{ 506 `-non-voting-server`, 507 `-data-dir=` + dataDir, 508 }, 509 patch: func(rt *RuntimeConfig) { 510 rt.NonVotingServer = true 511 rt.DataDir = dataDir 512 }, 513 }, 514 { 515 desc: "-pid-file", 516 args: []string{ 517 `-pid-file=a`, 518 `-data-dir=` + dataDir, 519 }, 520 patch: func(rt *RuntimeConfig) { 521 rt.PidFile = "a" 522 rt.DataDir = dataDir 523 }, 524 }, 525 { 526 desc: "-protocol", 527 args: []string{ 528 `-protocol=1`, 529 `-data-dir=` + dataDir, 530 }, 531 patch: func(rt *RuntimeConfig) { 532 rt.RPCProtocol = 1 533 rt.DataDir = dataDir 534 }, 535 }, 536 { 537 desc: "-raft-protocol", 538 args: []string{ 539 `-raft-protocol=1`, 540 `-data-dir=` + dataDir, 541 }, 542 patch: func(rt *RuntimeConfig) { 543 rt.RaftProtocol = 1 544 rt.DataDir = dataDir 545 }, 546 }, 547 { 548 desc: "-recursor", 549 args: []string{ 550 `-recursor=1.2.3.4`, 551 `-recursor=5.6.7.8`, 552 `-data-dir=` + dataDir, 553 }, 554 patch: func(rt *RuntimeConfig) { 555 rt.DNSRecursors = []string{"1.2.3.4", "5.6.7.8"} 556 rt.DataDir = dataDir 557 }, 558 }, 559 { 560 desc: "-rejoin", 561 args: []string{ 562 `-rejoin`, 563 `-data-dir=` + dataDir, 564 }, 565 patch: func(rt *RuntimeConfig) { 566 rt.RejoinAfterLeave = true 567 rt.DataDir = dataDir 568 }, 569 }, 570 { 571 desc: "-retry-interval", 572 args: []string{ 573 `-retry-interval=5s`, 574 `-data-dir=` + dataDir, 575 }, 576 patch: func(rt *RuntimeConfig) { 577 rt.RetryJoinIntervalLAN = 5 * time.Second 578 rt.DataDir = dataDir 579 }, 580 }, 581 { 582 desc: "-retry-interval-wan", 583 args: []string{ 584 `-retry-interval-wan=5s`, 585 `-data-dir=` + dataDir, 586 }, 587 patch: func(rt *RuntimeConfig) { 588 rt.RetryJoinIntervalWAN = 5 * time.Second 589 rt.DataDir = dataDir 590 }, 591 }, 592 { 593 desc: "-retry-join", 594 args: []string{ 595 `-retry-join=a`, 596 `-retry-join=b`, 597 `-data-dir=` + dataDir, 598 }, 599 patch: func(rt *RuntimeConfig) { 600 rt.RetryJoinLAN = []string{"a", "b"} 601 rt.DataDir = dataDir 602 }, 603 }, 604 { 605 desc: "-retry-join-wan", 606 args: []string{ 607 `-retry-join-wan=a`, 608 `-retry-join-wan=b`, 609 `-data-dir=` + dataDir, 610 }, 611 patch: func(rt *RuntimeConfig) { 612 rt.RetryJoinWAN = []string{"a", "b"} 613 rt.DataDir = dataDir 614 }, 615 }, 616 { 617 desc: "-retry-max", 618 args: []string{ 619 `-retry-max=1`, 620 `-data-dir=` + dataDir, 621 }, 622 patch: func(rt *RuntimeConfig) { 623 rt.RetryJoinMaxAttemptsLAN = 1 624 rt.DataDir = dataDir 625 }, 626 }, 627 { 628 desc: "-retry-max-wan", 629 args: []string{ 630 `-retry-max-wan=1`, 631 `-data-dir=` + dataDir, 632 }, 633 patch: func(rt *RuntimeConfig) { 634 rt.RetryJoinMaxAttemptsWAN = 1 635 rt.DataDir = dataDir 636 }, 637 }, 638 { 639 desc: "-serf-lan-bind", 640 args: []string{ 641 `-serf-lan-bind=1.2.3.4`, 642 `-data-dir=` + dataDir, 643 }, 644 patch: func(rt *RuntimeConfig) { 645 rt.SerfBindAddrLAN = tcpAddr("1.2.3.4:8301") 646 rt.DataDir = dataDir 647 }, 648 }, 649 { 650 desc: "-serf-lan-port", 651 args: []string{ 652 `-serf-lan-port=123`, 653 `-data-dir=` + dataDir, 654 }, 655 patch: func(rt *RuntimeConfig) { 656 rt.SerfPortLAN = 123 657 rt.SerfAdvertiseAddrLAN = tcpAddr("10.0.0.1:123") 658 rt.SerfBindAddrLAN = tcpAddr("0.0.0.0:123") 659 rt.DataDir = dataDir 660 }, 661 }, 662 { 663 desc: "-serf-wan-bind", 664 args: []string{ 665 `-serf-wan-bind=1.2.3.4`, 666 `-data-dir=` + dataDir, 667 }, 668 patch: func(rt *RuntimeConfig) { 669 rt.SerfBindAddrWAN = tcpAddr("1.2.3.4:8302") 670 rt.DataDir = dataDir 671 }, 672 }, 673 { 674 desc: "-serf-wan-port", 675 args: []string{ 676 `-serf-wan-port=123`, 677 `-data-dir=` + dataDir, 678 }, 679 patch: func(rt *RuntimeConfig) { 680 rt.SerfPortWAN = 123 681 rt.SerfAdvertiseAddrWAN = tcpAddr("10.0.0.1:123") 682 rt.SerfBindAddrWAN = tcpAddr("0.0.0.0:123") 683 rt.DataDir = dataDir 684 }, 685 }, 686 { 687 desc: "-server", 688 args: []string{ 689 `-server`, 690 `-data-dir=` + dataDir, 691 }, 692 patch: func(rt *RuntimeConfig) { 693 rt.ServerMode = true 694 rt.LeaveOnTerm = false 695 rt.SkipLeaveOnInt = true 696 rt.DataDir = dataDir 697 }, 698 }, 699 { 700 desc: "-server-port", 701 args: []string{ 702 `-server-port=123`, 703 `-data-dir=` + dataDir, 704 }, 705 patch: func(rt *RuntimeConfig) { 706 rt.ServerPort = 123 707 rt.RPCAdvertiseAddr = tcpAddr("10.0.0.1:123") 708 rt.RPCBindAddr = tcpAddr("0.0.0.0:123") 709 rt.DataDir = dataDir 710 }, 711 }, 712 { 713 desc: "-syslog", 714 args: []string{ 715 `-syslog`, 716 `-data-dir=` + dataDir, 717 }, 718 patch: func(rt *RuntimeConfig) { 719 rt.EnableSyslog = true 720 rt.DataDir = dataDir 721 }, 722 }, 723 { 724 desc: "-ui", 725 args: []string{ 726 `-ui`, 727 `-data-dir=` + dataDir, 728 }, 729 patch: func(rt *RuntimeConfig) { 730 rt.EnableUI = true 731 rt.DataDir = dataDir 732 }, 733 }, 734 { 735 desc: "-ui-dir", 736 args: []string{ 737 `-ui-dir=a`, 738 `-data-dir=` + dataDir, 739 }, 740 patch: func(rt *RuntimeConfig) { 741 rt.UIDir = "a" 742 rt.DataDir = dataDir 743 }, 744 }, 745 746 // ------------------------------------------------------------ 747 // ports and addresses 748 // 749 750 { 751 desc: "bind addr any v4", 752 args: []string{`-data-dir=` + dataDir}, 753 json: []string{`{ "bind_addr":"0.0.0.0" }`}, 754 hcl: []string{`bind_addr = "0.0.0.0"`}, 755 patch: func(rt *RuntimeConfig) { 756 rt.AdvertiseAddrLAN = ipAddr("10.0.0.1") 757 rt.AdvertiseAddrWAN = ipAddr("10.0.0.1") 758 rt.BindAddr = ipAddr("0.0.0.0") 759 rt.RPCAdvertiseAddr = tcpAddr("10.0.0.1:8300") 760 rt.RPCBindAddr = tcpAddr("0.0.0.0:8300") 761 rt.SerfAdvertiseAddrLAN = tcpAddr("10.0.0.1:8301") 762 rt.SerfAdvertiseAddrWAN = tcpAddr("10.0.0.1:8302") 763 rt.SerfBindAddrLAN = tcpAddr("0.0.0.0:8301") 764 rt.SerfBindAddrWAN = tcpAddr("0.0.0.0:8302") 765 rt.TaggedAddresses = map[string]string{ 766 "lan": "10.0.0.1", 767 "wan": "10.0.0.1", 768 } 769 rt.DataDir = dataDir 770 }, 771 }, 772 { 773 desc: "bind addr any v6", 774 args: []string{`-data-dir=` + dataDir}, 775 json: []string{`{ "bind_addr":"::" }`}, 776 hcl: []string{`bind_addr = "::"`}, 777 patch: func(rt *RuntimeConfig) { 778 rt.AdvertiseAddrLAN = ipAddr("dead:beef::1") 779 rt.AdvertiseAddrWAN = ipAddr("dead:beef::1") 780 rt.BindAddr = ipAddr("::") 781 rt.RPCAdvertiseAddr = tcpAddr("[dead:beef::1]:8300") 782 rt.RPCBindAddr = tcpAddr("[::]:8300") 783 rt.SerfAdvertiseAddrLAN = tcpAddr("[dead:beef::1]:8301") 784 rt.SerfAdvertiseAddrWAN = tcpAddr("[dead:beef::1]:8302") 785 rt.SerfBindAddrLAN = tcpAddr("[::]:8301") 786 rt.SerfBindAddrWAN = tcpAddr("[::]:8302") 787 rt.TaggedAddresses = map[string]string{ 788 "lan": "dead:beef::1", 789 "wan": "dead:beef::1", 790 } 791 rt.DataDir = dataDir 792 }, 793 publicv6: func() ([]*net.IPAddr, error) { 794 return []*net.IPAddr{ipAddr("dead:beef::1")}, nil 795 }, 796 }, 797 { 798 desc: "bind addr any and advertise set should not detect", 799 args: []string{`-data-dir=` + dataDir}, 800 json: []string{`{ "bind_addr":"0.0.0.0", "advertise_addr": "1.2.3.4" }`}, 801 hcl: []string{`bind_addr = "0.0.0.0" advertise_addr = "1.2.3.4"`}, 802 patch: func(rt *RuntimeConfig) { 803 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 804 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 805 rt.BindAddr = ipAddr("0.0.0.0") 806 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:8300") 807 rt.RPCBindAddr = tcpAddr("0.0.0.0:8300") 808 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:8301") 809 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 810 rt.SerfBindAddrLAN = tcpAddr("0.0.0.0:8301") 811 rt.SerfBindAddrWAN = tcpAddr("0.0.0.0:8302") 812 rt.TaggedAddresses = map[string]string{ 813 "lan": "1.2.3.4", 814 "wan": "1.2.3.4", 815 } 816 rt.DataDir = dataDir 817 }, 818 privatev4: func() ([]*net.IPAddr, error) { 819 return nil, fmt.Errorf("should not detect advertise_addr") 820 }, 821 }, 822 { 823 desc: "client addr and ports == 0", 824 args: []string{`-data-dir=` + dataDir}, 825 json: []string{`{ 826 "client_addr":"0.0.0.0", 827 "ports":{} 828 }`}, 829 hcl: []string{` 830 client_addr = "0.0.0.0" 831 ports {} 832 `}, 833 patch: func(rt *RuntimeConfig) { 834 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 835 rt.DNSAddrs = []net.Addr{tcpAddr("0.0.0.0:8600"), udpAddr("0.0.0.0:8600")} 836 rt.HTTPAddrs = []net.Addr{tcpAddr("0.0.0.0:8500")} 837 rt.DataDir = dataDir 838 }, 839 }, 840 { 841 desc: "client addr and ports < 0", 842 args: []string{`-data-dir=` + dataDir}, 843 json: []string{`{ 844 "client_addr":"0.0.0.0", 845 "ports": { "dns":-1, "http":-2, "https":-3, "grpc":-4 } 846 }`}, 847 hcl: []string{` 848 client_addr = "0.0.0.0" 849 ports { dns = -1 http = -2 https = -3 grpc = -4 } 850 `}, 851 patch: func(rt *RuntimeConfig) { 852 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 853 rt.DNSPort = -1 854 rt.DNSAddrs = nil 855 rt.HTTPPort = -1 856 rt.HTTPAddrs = nil 857 // HTTPS and gRPC default to disabled so shouldn't be different from 858 // default rt. 859 rt.DataDir = dataDir 860 }, 861 }, 862 { 863 desc: "client addr and ports > 0", 864 args: []string{`-data-dir=` + dataDir}, 865 json: []string{`{ 866 "client_addr":"0.0.0.0", 867 "ports":{ "dns": 1, "http": 2, "https": 3, "grpc": 4 } 868 }`}, 869 hcl: []string{` 870 client_addr = "0.0.0.0" 871 ports { dns = 1 http = 2 https = 3 grpc = 4 } 872 `}, 873 patch: func(rt *RuntimeConfig) { 874 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 875 rt.DNSPort = 1 876 rt.DNSAddrs = []net.Addr{tcpAddr("0.0.0.0:1"), udpAddr("0.0.0.0:1")} 877 rt.HTTPPort = 2 878 rt.HTTPAddrs = []net.Addr{tcpAddr("0.0.0.0:2")} 879 rt.HTTPSPort = 3 880 rt.HTTPSAddrs = []net.Addr{tcpAddr("0.0.0.0:3")} 881 rt.GRPCPort = 4 882 rt.GRPCAddrs = []net.Addr{tcpAddr("0.0.0.0:4")} 883 rt.DataDir = dataDir 884 }, 885 }, 886 887 { 888 desc: "client addr, addresses and ports == 0", 889 args: []string{`-data-dir=` + dataDir}, 890 json: []string{`{ 891 "client_addr":"0.0.0.0", 892 "addresses": { "dns": "1.1.1.1", "http": "2.2.2.2", "https": "3.3.3.3", "grpc": "4.4.4.4" }, 893 "ports":{} 894 }`}, 895 hcl: []string{` 896 client_addr = "0.0.0.0" 897 addresses = { dns = "1.1.1.1" http = "2.2.2.2" https = "3.3.3.3" grpc = "4.4.4.4" } 898 ports {} 899 `}, 900 patch: func(rt *RuntimeConfig) { 901 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 902 rt.DNSAddrs = []net.Addr{tcpAddr("1.1.1.1:8600"), udpAddr("1.1.1.1:8600")} 903 rt.HTTPAddrs = []net.Addr{tcpAddr("2.2.2.2:8500")} 904 // HTTPS and gRPC default to disabled so shouldn't be different from 905 // default rt. 906 rt.DataDir = dataDir 907 }, 908 }, 909 { 910 desc: "client addr, addresses and ports < 0", 911 args: []string{`-data-dir=` + dataDir}, 912 json: []string{`{ 913 "client_addr":"0.0.0.0", 914 "addresses": { "dns": "1.1.1.1", "http": "2.2.2.2", "https": "3.3.3.3", "grpc": "4.4.4.4" }, 915 "ports": { "dns":-1, "http":-2, "https":-3, "grpc":-4 } 916 }`}, 917 hcl: []string{` 918 client_addr = "0.0.0.0" 919 addresses = { dns = "1.1.1.1" http = "2.2.2.2" https = "3.3.3.3" grpc = "4.4.4.4" } 920 ports { dns = -1 http = -2 https = -3 grpc = -4 } 921 `}, 922 patch: func(rt *RuntimeConfig) { 923 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 924 rt.DNSPort = -1 925 rt.DNSAddrs = nil 926 rt.HTTPPort = -1 927 rt.HTTPAddrs = nil 928 // HTTPS and gRPC default to disabled so shouldn't be different from 929 // default rt. 930 rt.DataDir = dataDir 931 }, 932 }, 933 { 934 desc: "client addr, addresses and ports", 935 args: []string{`-data-dir=` + dataDir}, 936 json: []string{`{ 937 "client_addr": "0.0.0.0", 938 "addresses": { "dns": "1.1.1.1", "http": "2.2.2.2", "https": "3.3.3.3", "grpc": "4.4.4.4" }, 939 "ports":{ "dns":1, "http":2, "https":3, "grpc":4 } 940 }`}, 941 hcl: []string{` 942 client_addr = "0.0.0.0" 943 addresses = { dns = "1.1.1.1" http = "2.2.2.2" https = "3.3.3.3" grpc = "4.4.4.4" } 944 ports { dns = 1 http = 2 https = 3 grpc = 4 } 945 `}, 946 patch: func(rt *RuntimeConfig) { 947 rt.ClientAddrs = []*net.IPAddr{ipAddr("0.0.0.0")} 948 rt.DNSPort = 1 949 rt.DNSAddrs = []net.Addr{tcpAddr("1.1.1.1:1"), udpAddr("1.1.1.1:1")} 950 rt.HTTPPort = 2 951 rt.HTTPAddrs = []net.Addr{tcpAddr("2.2.2.2:2")} 952 rt.HTTPSPort = 3 953 rt.HTTPSAddrs = []net.Addr{tcpAddr("3.3.3.3:3")} 954 rt.GRPCPort = 4 955 rt.GRPCAddrs = []net.Addr{tcpAddr("4.4.4.4:4")} 956 rt.DataDir = dataDir 957 }, 958 }, 959 { 960 desc: "client template and ports", 961 args: []string{`-data-dir=` + dataDir}, 962 json: []string{`{ 963 "client_addr": "{{ printf \"1.2.3.4 2001:db8::1\" }}", 964 "ports":{ "dns":1, "http":2, "https":3, "grpc":4 } 965 }`}, 966 hcl: []string{` 967 client_addr = "{{ printf \"1.2.3.4 2001:db8::1\" }}" 968 ports { dns = 1 http = 2 https = 3 grpc = 4 } 969 `}, 970 patch: func(rt *RuntimeConfig) { 971 rt.ClientAddrs = []*net.IPAddr{ipAddr("1.2.3.4"), ipAddr("2001:db8::1")} 972 rt.DNSPort = 1 973 rt.DNSAddrs = []net.Addr{tcpAddr("1.2.3.4:1"), tcpAddr("[2001:db8::1]:1"), udpAddr("1.2.3.4:1"), udpAddr("[2001:db8::1]:1")} 974 rt.HTTPPort = 2 975 rt.HTTPAddrs = []net.Addr{tcpAddr("1.2.3.4:2"), tcpAddr("[2001:db8::1]:2")} 976 rt.HTTPSPort = 3 977 rt.HTTPSAddrs = []net.Addr{tcpAddr("1.2.3.4:3"), tcpAddr("[2001:db8::1]:3")} 978 rt.GRPCPort = 4 979 rt.GRPCAddrs = []net.Addr{tcpAddr("1.2.3.4:4"), tcpAddr("[2001:db8::1]:4")} 980 rt.DataDir = dataDir 981 }, 982 }, 983 { 984 desc: "client, address template and ports", 985 args: []string{`-data-dir=` + dataDir}, 986 json: []string{`{ 987 "client_addr": "{{ printf \"1.2.3.4 2001:db8::1\" }}", 988 "addresses": { 989 "dns": "{{ printf \"1.1.1.1 2001:db8::10 \" }}", 990 "http": "{{ printf \"2.2.2.2 unix://http 2001:db8::20 \" }}", 991 "https": "{{ printf \"3.3.3.3 unix://https 2001:db8::30 \" }}", 992 "grpc": "{{ printf \"4.4.4.4 unix://grpc 2001:db8::40 \" }}" 993 }, 994 "ports":{ "dns":1, "http":2, "https":3, "grpc":4 } 995 }`}, 996 hcl: []string{` 997 client_addr = "{{ printf \"1.2.3.4 2001:db8::1\" }}" 998 addresses = { 999 dns = "{{ printf \"1.1.1.1 2001:db8::10 \" }}" 1000 http = "{{ printf \"2.2.2.2 unix://http 2001:db8::20 \" }}" 1001 https = "{{ printf \"3.3.3.3 unix://https 2001:db8::30 \" }}" 1002 grpc = "{{ printf \"4.4.4.4 unix://grpc 2001:db8::40 \" }}" 1003 } 1004 ports { dns = 1 http = 2 https = 3 grpc = 4 } 1005 `}, 1006 patch: func(rt *RuntimeConfig) { 1007 rt.ClientAddrs = []*net.IPAddr{ipAddr("1.2.3.4"), ipAddr("2001:db8::1")} 1008 rt.DNSPort = 1 1009 rt.DNSAddrs = []net.Addr{tcpAddr("1.1.1.1:1"), tcpAddr("[2001:db8::10]:1"), udpAddr("1.1.1.1:1"), udpAddr("[2001:db8::10]:1")} 1010 rt.HTTPPort = 2 1011 rt.HTTPAddrs = []net.Addr{tcpAddr("2.2.2.2:2"), unixAddr("unix://http"), tcpAddr("[2001:db8::20]:2")} 1012 rt.HTTPSPort = 3 1013 rt.HTTPSAddrs = []net.Addr{tcpAddr("3.3.3.3:3"), unixAddr("unix://https"), tcpAddr("[2001:db8::30]:3")} 1014 rt.GRPCPort = 4 1015 rt.GRPCAddrs = []net.Addr{tcpAddr("4.4.4.4:4"), unixAddr("unix://grpc"), tcpAddr("[2001:db8::40]:4")} 1016 rt.DataDir = dataDir 1017 }, 1018 }, 1019 { 1020 desc: "advertise address lan template", 1021 args: []string{`-data-dir=` + dataDir}, 1022 json: []string{`{ "advertise_addr": "{{ printf \"1.2.3.4\" }}" }`}, 1023 hcl: []string{`advertise_addr = "{{ printf \"1.2.3.4\" }}"`}, 1024 patch: func(rt *RuntimeConfig) { 1025 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 1026 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 1027 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:8300") 1028 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:8301") 1029 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 1030 rt.TaggedAddresses = map[string]string{ 1031 "lan": "1.2.3.4", 1032 "wan": "1.2.3.4", 1033 } 1034 rt.DataDir = dataDir 1035 }, 1036 }, 1037 { 1038 desc: "advertise address wan template", 1039 args: []string{`-data-dir=` + dataDir}, 1040 json: []string{`{ "advertise_addr_wan": "{{ printf \"1.2.3.4\" }}" }`}, 1041 hcl: []string{`advertise_addr_wan = "{{ printf \"1.2.3.4\" }}"`}, 1042 patch: func(rt *RuntimeConfig) { 1043 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 1044 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:8302") 1045 rt.TaggedAddresses = map[string]string{ 1046 "lan": "10.0.0.1", 1047 "wan": "1.2.3.4", 1048 } 1049 rt.DataDir = dataDir 1050 }, 1051 }, 1052 { 1053 desc: "advertise address lan with ports", 1054 args: []string{`-data-dir=` + dataDir}, 1055 json: []string{`{ 1056 "ports": { 1057 "server": 1000, 1058 "serf_lan": 2000, 1059 "serf_wan": 3000 1060 }, 1061 "advertise_addr": "1.2.3.4" 1062 }`}, 1063 hcl: []string{` 1064 ports { 1065 server = 1000 1066 serf_lan = 2000 1067 serf_wan = 3000 1068 } 1069 advertise_addr = "1.2.3.4" 1070 `}, 1071 patch: func(rt *RuntimeConfig) { 1072 rt.AdvertiseAddrLAN = ipAddr("1.2.3.4") 1073 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 1074 rt.RPCAdvertiseAddr = tcpAddr("1.2.3.4:1000") 1075 rt.RPCBindAddr = tcpAddr("0.0.0.0:1000") 1076 rt.SerfAdvertiseAddrLAN = tcpAddr("1.2.3.4:2000") 1077 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:3000") 1078 rt.SerfBindAddrLAN = tcpAddr("0.0.0.0:2000") 1079 rt.SerfBindAddrWAN = tcpAddr("0.0.0.0:3000") 1080 rt.SerfPortLAN = 2000 1081 rt.SerfPortWAN = 3000 1082 rt.ServerPort = 1000 1083 rt.TaggedAddresses = map[string]string{ 1084 "lan": "1.2.3.4", 1085 "wan": "1.2.3.4", 1086 } 1087 rt.DataDir = dataDir 1088 }, 1089 }, 1090 { 1091 desc: "advertise address wan with ports", 1092 args: []string{`-data-dir=` + dataDir}, 1093 json: []string{`{ 1094 "ports": { 1095 "server": 1000, 1096 "serf_lan": 2000, 1097 "serf_wan": 3000 1098 }, 1099 "advertise_addr_wan": "1.2.3.4" 1100 }`}, 1101 hcl: []string{` 1102 ports { 1103 server = 1000 1104 serf_lan = 2000 1105 serf_wan = 3000 1106 } 1107 advertise_addr_wan = "1.2.3.4" 1108 `}, 1109 patch: func(rt *RuntimeConfig) { 1110 rt.AdvertiseAddrLAN = ipAddr("10.0.0.1") 1111 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 1112 rt.RPCAdvertiseAddr = tcpAddr("10.0.0.1:1000") 1113 rt.RPCBindAddr = tcpAddr("0.0.0.0:1000") 1114 rt.SerfAdvertiseAddrLAN = tcpAddr("10.0.0.1:2000") 1115 rt.SerfAdvertiseAddrWAN = tcpAddr("1.2.3.4:3000") 1116 rt.SerfBindAddrLAN = tcpAddr("0.0.0.0:2000") 1117 rt.SerfBindAddrWAN = tcpAddr("0.0.0.0:3000") 1118 rt.SerfPortLAN = 2000 1119 rt.SerfPortWAN = 3000 1120 rt.ServerPort = 1000 1121 rt.TaggedAddresses = map[string]string{ 1122 "lan": "10.0.0.1", 1123 "wan": "1.2.3.4", 1124 } 1125 rt.DataDir = dataDir 1126 }, 1127 }, 1128 { 1129 desc: "allow disabling serf wan port", 1130 args: []string{`-data-dir=` + dataDir}, 1131 json: []string{`{ 1132 "ports": { 1133 "serf_wan": -1 1134 }, 1135 "advertise_addr_wan": "1.2.3.4" 1136 }`}, 1137 hcl: []string{` 1138 ports { 1139 serf_wan = -1 1140 } 1141 advertise_addr_wan = "1.2.3.4" 1142 `}, 1143 patch: func(rt *RuntimeConfig) { 1144 rt.AdvertiseAddrWAN = ipAddr("1.2.3.4") 1145 rt.SerfAdvertiseAddrWAN = nil 1146 rt.SerfBindAddrWAN = nil 1147 rt.TaggedAddresses = map[string]string{ 1148 "lan": "10.0.0.1", 1149 "wan": "1.2.3.4", 1150 } 1151 rt.DataDir = dataDir 1152 rt.SerfPortWAN = -1 1153 }, 1154 }, 1155 { 1156 desc: "serf bind address lan template", 1157 args: []string{`-data-dir=` + dataDir}, 1158 json: []string{`{ "serf_lan": "{{ printf \"1.2.3.4\" }}" }`}, 1159 hcl: []string{`serf_lan = "{{ printf \"1.2.3.4\" }}"`}, 1160 patch: func(rt *RuntimeConfig) { 1161 rt.SerfBindAddrLAN = tcpAddr("1.2.3.4:8301") 1162 rt.DataDir = dataDir 1163 }, 1164 }, 1165 { 1166 desc: "serf bind address wan template", 1167 args: []string{`-data-dir=` + dataDir}, 1168 json: []string{`{ "serf_wan": "{{ printf \"1.2.3.4\" }}" }`}, 1169 hcl: []string{`serf_wan = "{{ printf \"1.2.3.4\" }}"`}, 1170 patch: func(rt *RuntimeConfig) { 1171 rt.SerfBindAddrWAN = tcpAddr("1.2.3.4:8302") 1172 rt.DataDir = dataDir 1173 }, 1174 }, 1175 { 1176 desc: "dns recursor templates with deduplication", 1177 args: []string{`-data-dir=` + dataDir}, 1178 json: []string{`{ "recursors": [ "{{ printf \"5.6.7.8:9999\" }}", "{{ printf \"1.2.3.4\" }}", "{{ printf \"5.6.7.8:9999\" }}" ] }`}, 1179 hcl: []string{`recursors = [ "{{ printf \"5.6.7.8:9999\" }}", "{{ printf \"1.2.3.4\" }}", "{{ printf \"5.6.7.8:9999\" }}" ] `}, 1180 patch: func(rt *RuntimeConfig) { 1181 rt.DNSRecursors = []string{"5.6.7.8:9999", "1.2.3.4"} 1182 rt.DataDir = dataDir 1183 }, 1184 }, 1185 { 1186 desc: "start_join address template", 1187 args: []string{`-data-dir=` + dataDir}, 1188 json: []string{`{ "start_join": ["{{ printf \"1.2.3.4 4.3.2.1\" }}"] }`}, 1189 hcl: []string{`start_join = ["{{ printf \"1.2.3.4 4.3.2.1\" }}"]`}, 1190 patch: func(rt *RuntimeConfig) { 1191 rt.StartJoinAddrsLAN = []string{"1.2.3.4", "4.3.2.1"} 1192 rt.DataDir = dataDir 1193 }, 1194 }, 1195 { 1196 desc: "start_join_wan address template", 1197 args: []string{`-data-dir=` + dataDir}, 1198 json: []string{`{ "start_join_wan": ["{{ printf \"1.2.3.4 4.3.2.1\" }}"] }`}, 1199 hcl: []string{`start_join_wan = ["{{ printf \"1.2.3.4 4.3.2.1\" }}"]`}, 1200 patch: func(rt *RuntimeConfig) { 1201 rt.StartJoinAddrsWAN = []string{"1.2.3.4", "4.3.2.1"} 1202 rt.DataDir = dataDir 1203 }, 1204 }, 1205 { 1206 desc: "retry_join address template", 1207 args: []string{`-data-dir=` + dataDir}, 1208 json: []string{`{ "retry_join": ["{{ printf \"1.2.3.4 4.3.2.1\" }}"] }`}, 1209 hcl: []string{`retry_join = ["{{ printf \"1.2.3.4 4.3.2.1\" }}"]`}, 1210 patch: func(rt *RuntimeConfig) { 1211 rt.RetryJoinLAN = []string{"1.2.3.4", "4.3.2.1"} 1212 rt.DataDir = dataDir 1213 }, 1214 }, 1215 { 1216 desc: "retry_join_wan address template", 1217 args: []string{`-data-dir=` + dataDir}, 1218 json: []string{`{ "retry_join_wan": ["{{ printf \"1.2.3.4 4.3.2.1\" }}"] }`}, 1219 hcl: []string{`retry_join_wan = ["{{ printf \"1.2.3.4 4.3.2.1\" }}"]`}, 1220 patch: func(rt *RuntimeConfig) { 1221 rt.RetryJoinWAN = []string{"1.2.3.4", "4.3.2.1"} 1222 rt.DataDir = dataDir 1223 }, 1224 }, 1225 1226 // ------------------------------------------------------------ 1227 // precedence rules 1228 // 1229 1230 { 1231 desc: "precedence: merge order", 1232 args: []string{`-data-dir=` + dataDir}, 1233 json: []string{ 1234 `{ 1235 "bootstrap": true, 1236 "bootstrap_expect": 1, 1237 "datacenter": "a", 1238 "start_join": ["a", "b"], 1239 "node_meta": {"a":"b"} 1240 }`, 1241 `{ 1242 "bootstrap": false, 1243 "bootstrap_expect": 0, 1244 "datacenter":"b", 1245 "start_join": ["c", "d"], 1246 "node_meta": {"a":"c"} 1247 }`, 1248 }, 1249 hcl: []string{ 1250 ` 1251 bootstrap = true 1252 bootstrap_expect = 1 1253 datacenter = "a" 1254 start_join = ["a", "b"] 1255 node_meta = { "a" = "b" } 1256 `, 1257 ` 1258 bootstrap = false 1259 bootstrap_expect = 0 1260 datacenter = "b" 1261 start_join = ["c", "d"] 1262 node_meta = { "a" = "c" } 1263 `, 1264 }, 1265 patch: func(rt *RuntimeConfig) { 1266 rt.Bootstrap = false 1267 rt.BootstrapExpect = 0 1268 rt.Datacenter = "b" 1269 rt.StartJoinAddrsLAN = []string{"a", "b", "c", "d"} 1270 rt.NodeMeta = map[string]string{"a": "c"} 1271 rt.DataDir = dataDir 1272 }, 1273 }, 1274 { 1275 desc: "precedence: flag before file", 1276 json: []string{ 1277 `{ 1278 "advertise_addr": "1.2.3.4", 1279 "advertise_addr_wan": "5.6.7.8", 1280 "bootstrap":true, 1281 "bootstrap_expect": 3, 1282 "datacenter":"a", 1283 "node_meta": {"a":"b"}, 1284 "recursors":["1.2.3.5", "5.6.7.9"], 1285 "serf_lan": "a", 1286 "serf_wan": "a", 1287 "start_join":["a", "b"] 1288 }`, 1289 }, 1290 hcl: []string{ 1291 ` 1292 advertise_addr = "1.2.3.4" 1293 advertise_addr_wan = "5.6.7.8" 1294 bootstrap = true 1295 bootstrap_expect = 3 1296 datacenter = "a" 1297 node_meta = { "a" = "b" } 1298 recursors = ["1.2.3.5", "5.6.7.9"] 1299 serf_lan = "a" 1300 serf_wan = "a" 1301 start_join = ["a", "b"] 1302 `, 1303 }, 1304 args: []string{ 1305 `-advertise=1.1.1.1`, 1306 `-advertise-wan=2.2.2.2`, 1307 `-bootstrap=false`, 1308 `-bootstrap-expect=0`, 1309 `-datacenter=b`, 1310 `-data-dir=` + dataDir, 1311 `-join`, `c`, `-join=d`, 1312 `-node-meta=a:c`, 1313 `-recursor`, `1.2.3.6`, `-recursor=5.6.7.10`, 1314 `-serf-lan-bind=3.3.3.3`, 1315 `-serf-wan-bind=4.4.4.4`, 1316 }, 1317 patch: func(rt *RuntimeConfig) { 1318 rt.AdvertiseAddrLAN = ipAddr("1.1.1.1") 1319 rt.AdvertiseAddrWAN = ipAddr("2.2.2.2") 1320 rt.RPCAdvertiseAddr = tcpAddr("1.1.1.1:8300") 1321 rt.SerfAdvertiseAddrLAN = tcpAddr("1.1.1.1:8301") 1322 rt.SerfAdvertiseAddrWAN = tcpAddr("2.2.2.2:8302") 1323 rt.Datacenter = "b" 1324 rt.DNSRecursors = []string{"1.2.3.6", "5.6.7.10", "1.2.3.5", "5.6.7.9"} 1325 rt.NodeMeta = map[string]string{"a": "c"} 1326 rt.SerfBindAddrLAN = tcpAddr("3.3.3.3:8301") 1327 rt.SerfBindAddrWAN = tcpAddr("4.4.4.4:8302") 1328 rt.StartJoinAddrsLAN = []string{"c", "d", "a", "b"} 1329 rt.TaggedAddresses = map[string]string{ 1330 "lan": "1.1.1.1", 1331 "wan": "2.2.2.2", 1332 } 1333 rt.DataDir = dataDir 1334 }, 1335 }, 1336 1337 // ------------------------------------------------------------ 1338 // transformations 1339 // 1340 1341 { 1342 desc: "raft performance scaling", 1343 args: []string{`-data-dir=` + dataDir}, 1344 json: []string{`{ "performance": { "raft_multiplier": 9} }`}, 1345 hcl: []string{`performance = { raft_multiplier=9 }`}, 1346 patch: func(rt *RuntimeConfig) { 1347 rt.ConsulRaftElectionTimeout = 9 * 1000 * time.Millisecond 1348 rt.ConsulRaftHeartbeatTimeout = 9 * 1000 * time.Millisecond 1349 rt.ConsulRaftLeaderLeaseTimeout = 9 * 500 * time.Millisecond 1350 rt.DataDir = dataDir 1351 }, 1352 }, 1353 1354 // ------------------------------------------------------------ 1355 // validations 1356 // 1357 1358 { 1359 desc: "invalid input", 1360 args: []string{`-data-dir=` + dataDir}, 1361 json: []string{`this is not JSON`}, 1362 hcl: []string{`*** 0123 this is not HCL`}, 1363 err: "Error parsing", 1364 }, 1365 { 1366 desc: "datacenter is lower-cased", 1367 args: []string{`-data-dir=` + dataDir}, 1368 json: []string{`{ "datacenter": "A" }`}, 1369 hcl: []string{`datacenter = "A"`}, 1370 patch: func(rt *RuntimeConfig) { 1371 rt.Datacenter = "a" 1372 rt.DataDir = dataDir 1373 }, 1374 }, 1375 { 1376 desc: "acl_datacenter is lower-cased", 1377 args: []string{`-data-dir=` + dataDir}, 1378 json: []string{`{ "acl_datacenter": "A" }`}, 1379 hcl: []string{`acl_datacenter = "A"`}, 1380 patch: func(rt *RuntimeConfig) { 1381 rt.ACLsEnabled = true 1382 rt.ACLDatacenter = "a" 1383 rt.DataDir = dataDir 1384 rt.PrimaryDatacenter = "a" 1385 }, 1386 warns: []string{`The 'acl_datacenter' field is deprecated. Use the 'primary_datacenter' field instead.`}, 1387 }, 1388 { 1389 desc: "acl_replication_token enables acl replication", 1390 args: []string{`-data-dir=` + dataDir}, 1391 json: []string{`{ "acl_replication_token": "a" }`}, 1392 hcl: []string{`acl_replication_token = "a"`}, 1393 patch: func(rt *RuntimeConfig) { 1394 rt.ACLReplicationToken = "a" 1395 rt.ACLTokenReplication = true 1396 rt.DataDir = dataDir 1397 }, 1398 }, 1399 { 1400 desc: "advertise address detect fails v4", 1401 args: []string{`-data-dir=` + dataDir}, 1402 json: []string{`{ "bind_addr": "0.0.0.0"}`}, 1403 hcl: []string{`bind_addr = "0.0.0.0"`}, 1404 privatev4: func() ([]*net.IPAddr, error) { 1405 return nil, errors.New("some error") 1406 }, 1407 err: "Error detecting private IPv4 address: some error", 1408 }, 1409 { 1410 desc: "advertise address detect none v4", 1411 args: []string{`-data-dir=` + dataDir}, 1412 json: []string{`{ "bind_addr": "0.0.0.0"}`}, 1413 hcl: []string{`bind_addr = "0.0.0.0"`}, 1414 privatev4: func() ([]*net.IPAddr, error) { 1415 return nil, nil 1416 }, 1417 err: "No private IPv4 address found", 1418 }, 1419 { 1420 desc: "advertise address detect multiple v4", 1421 args: []string{`-data-dir=` + dataDir}, 1422 json: []string{`{ "bind_addr": "0.0.0.0"}`}, 1423 hcl: []string{`bind_addr = "0.0.0.0"`}, 1424 privatev4: func() ([]*net.IPAddr, error) { 1425 return []*net.IPAddr{ipAddr("1.1.1.1"), ipAddr("2.2.2.2")}, nil 1426 }, 1427 err: "Multiple private IPv4 addresses found. Please configure one", 1428 }, 1429 { 1430 desc: "advertise address detect fails v6", 1431 args: []string{`-data-dir=` + dataDir}, 1432 json: []string{`{ "bind_addr": "::"}`}, 1433 hcl: []string{`bind_addr = "::"`}, 1434 publicv6: func() ([]*net.IPAddr, error) { 1435 return nil, errors.New("some error") 1436 }, 1437 err: "Error detecting public IPv6 address: some error", 1438 }, 1439 { 1440 desc: "advertise address detect none v6", 1441 args: []string{`-data-dir=` + dataDir}, 1442 json: []string{`{ "bind_addr": "::"}`}, 1443 hcl: []string{`bind_addr = "::"`}, 1444 publicv6: func() ([]*net.IPAddr, error) { 1445 return nil, nil 1446 }, 1447 err: "No public IPv6 address found", 1448 }, 1449 { 1450 desc: "advertise address detect multiple v6", 1451 args: []string{`-data-dir=` + dataDir}, 1452 json: []string{`{ "bind_addr": "::"}`}, 1453 hcl: []string{`bind_addr = "::"`}, 1454 publicv6: func() ([]*net.IPAddr, error) { 1455 return []*net.IPAddr{ipAddr("dead:beef::1"), ipAddr("dead:beef::2")}, nil 1456 }, 1457 err: "Multiple public IPv6 addresses found. Please configure one", 1458 }, 1459 { 1460 desc: "ae_interval invalid == 0", 1461 args: []string{`-data-dir=` + dataDir}, 1462 jsontail: []string{`{ "ae_interval": "0s" }`}, 1463 hcltail: []string{`ae_interval = "0s"`}, 1464 err: `ae_interval cannot be 0s. Must be positive`, 1465 }, 1466 { 1467 desc: "ae_interval invalid < 0", 1468 args: []string{`-data-dir=` + dataDir}, 1469 jsontail: []string{`{ "ae_interval": "-1s" }`}, 1470 hcltail: []string{`ae_interval = "-1s"`}, 1471 err: `ae_interval cannot be -1s. Must be positive`, 1472 }, 1473 { 1474 desc: "acl_datacenter invalid", 1475 args: []string{ 1476 `-datacenter=a`, 1477 `-data-dir=` + dataDir, 1478 }, 1479 json: []string{`{ "acl_datacenter": "%" }`}, 1480 hcl: []string{`acl_datacenter = "%"`}, 1481 err: `acl_datacenter cannot be "%". Please use only [a-z0-9-_]`, 1482 warns: []string{`The 'acl_datacenter' field is deprecated. Use the 'primary_datacenter' field instead.`}, 1483 }, 1484 { 1485 desc: "autopilot.max_trailing_logs invalid", 1486 args: []string{ 1487 `-datacenter=a`, 1488 `-data-dir=` + dataDir, 1489 }, 1490 json: []string{`{ "autopilot": { "max_trailing_logs": -1 } }`}, 1491 hcl: []string{`autopilot = { max_trailing_logs = -1 }`}, 1492 err: "autopilot.max_trailing_logs cannot be -1. Must be greater than or equal to zero", 1493 }, 1494 { 1495 desc: "bind_addr cannot be empty", 1496 args: []string{`-data-dir=` + dataDir}, 1497 json: []string{`{ "bind_addr": "" }`}, 1498 hcl: []string{`bind_addr = ""`}, 1499 err: "bind_addr cannot be empty", 1500 }, 1501 { 1502 desc: "bind_addr does not allow multiple addresses", 1503 args: []string{`-data-dir=` + dataDir}, 1504 json: []string{`{ "bind_addr": "1.1.1.1 2.2.2.2" }`}, 1505 hcl: []string{`bind_addr = "1.1.1.1 2.2.2.2"`}, 1506 err: "bind_addr cannot contain multiple addresses", 1507 }, 1508 { 1509 desc: "bind_addr cannot be a unix socket", 1510 args: []string{`-data-dir=` + dataDir}, 1511 json: []string{`{ "bind_addr": "unix:///foo" }`}, 1512 hcl: []string{`bind_addr = "unix:///foo"`}, 1513 err: "bind_addr cannot be a unix socket", 1514 }, 1515 { 1516 desc: "bootstrap without server", 1517 args: []string{ 1518 `-datacenter=a`, 1519 `-data-dir=` + dataDir, 1520 }, 1521 json: []string{`{ "bootstrap": true }`}, 1522 hcl: []string{`bootstrap = true`}, 1523 err: "'bootstrap = true' requires 'server = true'", 1524 }, 1525 { 1526 desc: "bootstrap-expect without server", 1527 args: []string{ 1528 `-datacenter=a`, 1529 `-data-dir=` + dataDir, 1530 }, 1531 json: []string{`{ "bootstrap_expect": 3 }`}, 1532 hcl: []string{`bootstrap_expect = 3`}, 1533 err: "'bootstrap_expect > 0' requires 'server = true'", 1534 }, 1535 { 1536 desc: "bootstrap-expect invalid", 1537 args: []string{ 1538 `-datacenter=a`, 1539 `-data-dir=` + dataDir, 1540 }, 1541 json: []string{`{ "bootstrap_expect": -1 }`}, 1542 hcl: []string{`bootstrap_expect = -1`}, 1543 err: "bootstrap_expect cannot be -1. Must be greater than or equal to zero", 1544 }, 1545 { 1546 desc: "bootstrap-expect and dev mode", 1547 args: []string{ 1548 `-dev`, 1549 `-datacenter=a`, 1550 `-data-dir=` + dataDir, 1551 }, 1552 json: []string{`{ "bootstrap_expect": 3, "server": true }`}, 1553 hcl: []string{`bootstrap_expect = 3 server = true`}, 1554 err: "'bootstrap_expect > 0' not allowed in dev mode", 1555 }, 1556 { 1557 desc: "bootstrap-expect and bootstrap", 1558 args: []string{ 1559 `-datacenter=a`, 1560 `-data-dir=` + dataDir, 1561 }, 1562 json: []string{`{ "bootstrap": true, "bootstrap_expect": 3, "server": true }`}, 1563 hcl: []string{`bootstrap = true bootstrap_expect = 3 server = true`}, 1564 err: "'bootstrap_expect > 0' and 'bootstrap = true' are mutually exclusive", 1565 }, 1566 { 1567 desc: "bootstrap-expect=1 equals bootstrap", 1568 args: []string{ 1569 `-data-dir=` + dataDir, 1570 }, 1571 json: []string{`{ "bootstrap_expect": 1, "server": true }`}, 1572 hcl: []string{`bootstrap_expect = 1 server = true`}, 1573 patch: func(rt *RuntimeConfig) { 1574 rt.Bootstrap = true 1575 rt.BootstrapExpect = 0 1576 rt.LeaveOnTerm = false 1577 rt.ServerMode = true 1578 rt.SkipLeaveOnInt = true 1579 rt.DataDir = dataDir 1580 }, 1581 warns: []string{"BootstrapExpect is set to 1; this is the same as Bootstrap mode.", "bootstrap = true: do not enable unless necessary"}, 1582 }, 1583 { 1584 desc: "bootstrap-expect=2 warning", 1585 args: []string{ 1586 `-data-dir=` + dataDir, 1587 }, 1588 json: []string{`{ "bootstrap_expect": 2, "server": true }`}, 1589 hcl: []string{`bootstrap_expect = 2 server = true`}, 1590 patch: func(rt *RuntimeConfig) { 1591 rt.BootstrapExpect = 2 1592 rt.LeaveOnTerm = false 1593 rt.ServerMode = true 1594 rt.SkipLeaveOnInt = true 1595 rt.DataDir = dataDir 1596 }, 1597 warns: []string{ 1598 `bootstrap_expect = 2: A cluster with 2 servers will provide no failure tolerance. See https://www.consul.io/docs/internals/consensus.html#deployment-table`, 1599 `bootstrap_expect > 0: expecting 2 servers`, 1600 }, 1601 }, 1602 { 1603 desc: "bootstrap-expect > 2 but even warning", 1604 args: []string{ 1605 `-data-dir=` + dataDir, 1606 }, 1607 json: []string{`{ "bootstrap_expect": 4, "server": true }`}, 1608 hcl: []string{`bootstrap_expect = 4 server = true`}, 1609 patch: func(rt *RuntimeConfig) { 1610 rt.BootstrapExpect = 4 1611 rt.LeaveOnTerm = false 1612 rt.ServerMode = true 1613 rt.SkipLeaveOnInt = true 1614 rt.DataDir = dataDir 1615 }, 1616 warns: []string{ 1617 `bootstrap_expect is even number: A cluster with an even number of servers does not achieve optimum fault tolerance. See https://www.consul.io/docs/internals/consensus.html#deployment-table`, 1618 `bootstrap_expect > 0: expecting 4 servers`, 1619 }, 1620 }, 1621 { 1622 desc: "client mode sets LeaveOnTerm and SkipLeaveOnInt correctly", 1623 args: []string{ 1624 `-data-dir=` + dataDir, 1625 }, 1626 json: []string{`{ "server": false }`}, 1627 hcl: []string{` server = false`}, 1628 patch: func(rt *RuntimeConfig) { 1629 rt.LeaveOnTerm = true 1630 rt.ServerMode = false 1631 rt.SkipLeaveOnInt = false 1632 rt.DataDir = dataDir 1633 }, 1634 }, 1635 { 1636 desc: "client does not allow socket", 1637 args: []string{ 1638 `-datacenter=a`, 1639 `-data-dir=` + dataDir, 1640 }, 1641 json: []string{`{ "client_addr": "unix:///foo" }`}, 1642 hcl: []string{`client_addr = "unix:///foo"`}, 1643 err: "client_addr cannot be a unix socket", 1644 }, 1645 { 1646 desc: "datacenter invalid", 1647 args: []string{`-data-dir=` + dataDir}, 1648 json: []string{`{ "datacenter": "%" }`}, 1649 hcl: []string{`datacenter = "%"`}, 1650 err: `datacenter cannot be "%". Please use only [a-z0-9-_]`, 1651 }, 1652 { 1653 desc: "dns does not allow socket", 1654 args: []string{ 1655 `-datacenter=a`, 1656 `-data-dir=` + dataDir, 1657 }, 1658 json: []string{`{ "addresses": {"dns": "unix:///foo" } }`}, 1659 hcl: []string{`addresses = { dns = "unix:///foo" }`}, 1660 err: "DNS address cannot be a unix socket", 1661 }, 1662 { 1663 desc: "ui and ui_dir", 1664 args: []string{ 1665 `-datacenter=a`, 1666 `-data-dir=` + dataDir, 1667 }, 1668 json: []string{`{ "ui": true, "ui_dir": "a" }`}, 1669 hcl: []string{`ui = true ui_dir = "a"`}, 1670 err: "Both the ui and ui-dir flags were specified, please provide only one.\n" + 1671 "If trying to use your own web UI resources, use the ui-dir flag.\n" + 1672 "If using Consul version 0.7.0 or later, the web UI is included in the binary so use ui to enable it", 1673 }, 1674 1675 // test ANY address failures 1676 // to avoid combinatory explosion for tests use 0.0.0.0, :: or [::] but not all of them 1677 { 1678 desc: "advertise_addr any", 1679 args: []string{ 1680 `-data-dir=` + dataDir, 1681 }, 1682 json: []string{`{ "advertise_addr": "0.0.0.0" }`}, 1683 hcl: []string{`advertise_addr = "0.0.0.0"`}, 1684 err: "Advertise address cannot be 0.0.0.0, :: or [::]", 1685 }, 1686 { 1687 desc: "advertise_addr_wan any", 1688 args: []string{ 1689 `-data-dir=` + dataDir, 1690 }, 1691 json: []string{`{ "advertise_addr_wan": "::" }`}, 1692 hcl: []string{`advertise_addr_wan = "::"`}, 1693 err: "Advertise WAN address cannot be 0.0.0.0, :: or [::]", 1694 }, 1695 { 1696 desc: "recursors any", 1697 args: []string{ 1698 `-data-dir=` + dataDir, 1699 }, 1700 json: []string{`{ "recursors": ["::"] }`}, 1701 hcl: []string{`recursors = ["::"]`}, 1702 err: "DNS recursor address cannot be 0.0.0.0, :: or [::]", 1703 }, 1704 { 1705 desc: "dns_config.udp_answer_limit invalid", 1706 args: []string{ 1707 `-data-dir=` + dataDir, 1708 }, 1709 json: []string{`{ "dns_config": { "udp_answer_limit": -1 } }`}, 1710 hcl: []string{`dns_config = { udp_answer_limit = -1 }`}, 1711 err: "dns_config.udp_answer_limit cannot be -1. Must be greater than or equal to zero", 1712 }, 1713 { 1714 desc: "dns_config.a_record_limit invalid", 1715 args: []string{ 1716 `-data-dir=` + dataDir, 1717 }, 1718 json: []string{`{ "dns_config": { "a_record_limit": -1 } }`}, 1719 hcl: []string{`dns_config = { a_record_limit = -1 }`}, 1720 err: "dns_config.a_record_limit cannot be -1. Must be greater than or equal to zero", 1721 }, 1722 { 1723 desc: "performance.raft_multiplier < 0", 1724 args: []string{ 1725 `-data-dir=` + dataDir, 1726 }, 1727 json: []string{`{ "performance": { "raft_multiplier": -1 } }`}, 1728 hcl: []string{`performance = { raft_multiplier = -1 }`}, 1729 err: `performance.raft_multiplier cannot be -1. Must be between 1 and 10`, 1730 }, 1731 { 1732 desc: "performance.raft_multiplier == 0", 1733 args: []string{ 1734 `-data-dir=` + dataDir, 1735 }, 1736 json: []string{`{ "performance": { "raft_multiplier": 0 } }`}, 1737 hcl: []string{`performance = { raft_multiplier = 0 }`}, 1738 err: `performance.raft_multiplier cannot be 0. Must be between 1 and 10`, 1739 }, 1740 { 1741 desc: "performance.raft_multiplier > 10", 1742 args: []string{ 1743 `-data-dir=` + dataDir, 1744 }, 1745 json: []string{`{ "performance": { "raft_multiplier": 20 } }`}, 1746 hcl: []string{`performance = { raft_multiplier = 20 }`}, 1747 err: `performance.raft_multiplier cannot be 20. Must be between 1 and 10`, 1748 }, 1749 { 1750 desc: "node_name invalid", 1751 args: []string{ 1752 `-data-dir=` + dataDir, 1753 `-node=`, 1754 }, 1755 hostname: func() (string, error) { return "", nil }, 1756 err: "node_name cannot be empty", 1757 }, 1758 { 1759 desc: "node_meta key too long", 1760 args: []string{ 1761 `-data-dir=` + dataDir, 1762 }, 1763 json: []string{ 1764 `{ "dns_config": { "udp_answer_limit": 1 } }`, 1765 `{ "node_meta": { "` + randomString(130) + `": "a" } }`, 1766 }, 1767 hcl: []string{ 1768 `dns_config = { udp_answer_limit = 1 }`, 1769 `node_meta = { "` + randomString(130) + `" = "a" }`, 1770 }, 1771 err: "Key is too long (limit: 128 characters)", 1772 }, 1773 { 1774 desc: "node_meta value too long", 1775 args: []string{ 1776 `-data-dir=` + dataDir, 1777 }, 1778 json: []string{ 1779 `{ "dns_config": { "udp_answer_limit": 1 } }`, 1780 `{ "node_meta": { "a": "` + randomString(520) + `" } }`, 1781 }, 1782 hcl: []string{ 1783 `dns_config = { udp_answer_limit = 1 }`, 1784 `node_meta = { "a" = "` + randomString(520) + `" }`, 1785 }, 1786 err: "Value is too long (limit: 512 characters)", 1787 }, 1788 { 1789 desc: "node_meta too many keys", 1790 args: []string{ 1791 `-data-dir=` + dataDir, 1792 }, 1793 json: []string{ 1794 `{ "dns_config": { "udp_answer_limit": 1 } }`, 1795 `{ "node_meta": {` + metaPairs(70, "json") + `} }`, 1796 }, 1797 hcl: []string{ 1798 `dns_config = { udp_answer_limit = 1 }`, 1799 `node_meta = {` + metaPairs(70, "hcl") + ` }`, 1800 }, 1801 err: "Node metadata cannot contain more than 64 key/value pairs", 1802 }, 1803 { 1804 desc: "unique listeners dns vs http", 1805 args: []string{ 1806 `-data-dir=` + dataDir, 1807 }, 1808 json: []string{`{ 1809 "client_addr": "1.2.3.4", 1810 "ports": { "dns": 1000, "http": 1000 } 1811 }`}, 1812 hcl: []string{` 1813 client_addr = "1.2.3.4" 1814 ports = { dns = 1000 http = 1000 } 1815 `}, 1816 err: "HTTP address 1.2.3.4:1000 already configured for DNS", 1817 }, 1818 { 1819 desc: "unique listeners dns vs https", 1820 args: []string{ 1821 `-data-dir=` + dataDir, 1822 }, 1823 json: []string{`{ 1824 "client_addr": "1.2.3.4", 1825 "ports": { "dns": 1000, "https": 1000 } 1826 }`}, 1827 hcl: []string{` 1828 client_addr = "1.2.3.4" 1829 ports = { dns = 1000 https = 1000 } 1830 `}, 1831 err: "HTTPS address 1.2.3.4:1000 already configured for DNS", 1832 }, 1833 { 1834 desc: "unique listeners http vs https", 1835 args: []string{ 1836 `-data-dir=` + dataDir, 1837 }, 1838 json: []string{`{ 1839 "client_addr": "1.2.3.4", 1840 "ports": { "http": 1000, "https": 1000 } 1841 }`}, 1842 hcl: []string{` 1843 client_addr = "1.2.3.4" 1844 ports = { http = 1000 https = 1000 } 1845 `}, 1846 err: "HTTPS address 1.2.3.4:1000 already configured for HTTP", 1847 }, 1848 { 1849 desc: "unique advertise addresses HTTP vs RPC", 1850 args: []string{ 1851 `-data-dir=` + dataDir, 1852 }, 1853 json: []string{`{ 1854 "addresses": { "http": "10.0.0.1" }, 1855 "ports": { "http": 1000, "server": 1000 } 1856 }`}, 1857 hcl: []string{` 1858 addresses = { http = "10.0.0.1" } 1859 ports = { http = 1000 server = 1000 } 1860 `}, 1861 err: "RPC Advertise address 10.0.0.1:1000 already configured for HTTP", 1862 }, 1863 { 1864 desc: "unique advertise addresses RPC vs Serf LAN", 1865 args: []string{ 1866 `-data-dir=` + dataDir, 1867 }, 1868 json: []string{`{ 1869 "ports": { "server": 1000, "serf_lan": 1000 } 1870 }`}, 1871 hcl: []string{` 1872 ports = { server = 1000 serf_lan = 1000 } 1873 `}, 1874 err: "Serf Advertise LAN address 10.0.0.1:1000 already configured for RPC Advertise", 1875 }, 1876 { 1877 desc: "unique advertise addresses RPC vs Serf WAN", 1878 args: []string{ 1879 `-data-dir=` + dataDir, 1880 }, 1881 json: []string{`{ 1882 "ports": { "server": 1000, "serf_wan": 1000 } 1883 }`}, 1884 hcl: []string{` 1885 ports = { server = 1000 serf_wan = 1000 } 1886 `}, 1887 err: "Serf Advertise WAN address 10.0.0.1:1000 already configured for RPC Advertise", 1888 }, 1889 { 1890 desc: "sidecar_service can't have ID", 1891 args: []string{ 1892 `-data-dir=` + dataDir, 1893 }, 1894 json: []string{`{ 1895 "service": { 1896 "name": "web", 1897 "port": 1234, 1898 "connect": { 1899 "sidecar_service": { 1900 "ID": "random-sidecar-id" 1901 } 1902 } 1903 } 1904 }`}, 1905 hcl: []string{` 1906 service { 1907 name = "web" 1908 port = 1234 1909 connect { 1910 sidecar_service { 1911 ID = "random-sidecar-id" 1912 } 1913 } 1914 } 1915 `}, 1916 err: "sidecar_service can't specify an ID", 1917 }, 1918 { 1919 desc: "sidecar_service can't have nested sidecar", 1920 args: []string{ 1921 `-data-dir=` + dataDir, 1922 }, 1923 json: []string{`{ 1924 "service": { 1925 "name": "web", 1926 "port": 1234, 1927 "connect": { 1928 "sidecar_service": { 1929 "connect": { 1930 "sidecar_service": {} 1931 } 1932 } 1933 } 1934 } 1935 }`}, 1936 hcl: []string{` 1937 service { 1938 name = "web" 1939 port = 1234 1940 connect { 1941 sidecar_service { 1942 connect { 1943 sidecar_service { 1944 } 1945 } 1946 } 1947 } 1948 } 1949 `}, 1950 err: "sidecar_service can't have a nested sidecar_service", 1951 }, 1952 { 1953 desc: "sidecar_service can't have managed proxy", 1954 args: []string{ 1955 `-data-dir=` + dataDir, 1956 }, 1957 json: []string{`{ 1958 "service": { 1959 "name": "web", 1960 "port": 1234, 1961 "connect": { 1962 "sidecar_service": { 1963 "connect": { 1964 "proxy": {} 1965 } 1966 } 1967 } 1968 } 1969 }`}, 1970 hcl: []string{` 1971 service { 1972 name = "web" 1973 port = 1234 1974 connect { 1975 sidecar_service { 1976 connect { 1977 proxy { 1978 } 1979 } 1980 } 1981 } 1982 } 1983 `}, 1984 err: "sidecar_service can't have a managed proxy", 1985 }, 1986 { 1987 desc: "telemetry.prefix_filter cannot be empty", 1988 args: []string{ 1989 `-data-dir=` + dataDir, 1990 }, 1991 json: []string{`{ 1992 "telemetry": { "prefix_filter": [""] } 1993 }`}, 1994 hcl: []string{` 1995 telemetry = { prefix_filter = [""] } 1996 `}, 1997 patch: func(rt *RuntimeConfig) { 1998 rt.DataDir = dataDir 1999 }, 2000 warns: []string{"Cannot have empty filter rule in prefix_filter"}, 2001 }, 2002 { 2003 desc: "telemetry.prefix_filter must start with + or -", 2004 args: []string{ 2005 `-data-dir=` + dataDir, 2006 }, 2007 json: []string{`{ 2008 "telemetry": { "prefix_filter": ["+foo", "-bar", "nix"] } 2009 }`}, 2010 hcl: []string{` 2011 telemetry = { prefix_filter = ["+foo", "-bar", "nix"] } 2012 `}, 2013 patch: func(rt *RuntimeConfig) { 2014 rt.DataDir = dataDir 2015 rt.Telemetry.AllowedPrefixes = []string{"foo"} 2016 rt.Telemetry.BlockedPrefixes = []string{"bar"} 2017 }, 2018 warns: []string{`Filter rule must begin with either '+' or '-': "nix"`}, 2019 }, 2020 { 2021 desc: "encrypt has invalid key", 2022 args: []string{ 2023 `-data-dir=` + dataDir, 2024 }, 2025 json: []string{`{ "encrypt": "this is not a valid key" }`}, 2026 hcl: []string{` encrypt = "this is not a valid key" `}, 2027 err: "encrypt has invalid key: illegal base64 data at input byte 4", 2028 }, 2029 { 2030 desc: "encrypt given but LAN keyring exists", 2031 args: []string{ 2032 `-data-dir=` + dataDir, 2033 }, 2034 json: []string{`{ "encrypt": "i0P+gFTkLPg0h53eNYjydg==" }`}, 2035 hcl: []string{` encrypt = "i0P+gFTkLPg0h53eNYjydg==" `}, 2036 patch: func(rt *RuntimeConfig) { 2037 rt.EncryptKey = "i0P+gFTkLPg0h53eNYjydg==" 2038 rt.DataDir = dataDir 2039 }, 2040 pre: func() { 2041 writeFile(filepath.Join(dataDir, SerfLANKeyring), []byte("i0P+gFTkLPg0h53eNYjydg==")) 2042 }, 2043 warns: []string{`WARNING: LAN keyring exists but -encrypt given, using keyring`}, 2044 }, 2045 { 2046 desc: "encrypt given but WAN keyring exists", 2047 args: []string{ 2048 `-data-dir=` + dataDir, 2049 }, 2050 json: []string{`{ "encrypt": "i0P+gFTkLPg0h53eNYjydg==", "server": true }`}, 2051 hcl: []string{` encrypt = "i0P+gFTkLPg0h53eNYjydg==" server = true `}, 2052 patch: func(rt *RuntimeConfig) { 2053 rt.EncryptKey = "i0P+gFTkLPg0h53eNYjydg==" 2054 rt.ServerMode = true 2055 rt.LeaveOnTerm = false 2056 rt.SkipLeaveOnInt = true 2057 rt.DataDir = dataDir 2058 }, 2059 pre: func() { 2060 writeFile(filepath.Join(dataDir, SerfWANKeyring), []byte("i0P+gFTkLPg0h53eNYjydg==")) 2061 }, 2062 warns: []string{`WARNING: WAN keyring exists but -encrypt given, using keyring`}, 2063 }, 2064 { 2065 desc: "multiple check files", 2066 args: []string{ 2067 `-data-dir=` + dataDir, 2068 }, 2069 json: []string{ 2070 `{ "check": { "name": "a", "args": ["/bin/true"] } }`, 2071 `{ "check": { "name": "b", "args": ["/bin/false"] } }`, 2072 }, 2073 hcl: []string{ 2074 `check = { name = "a" args = ["/bin/true"] }`, 2075 `check = { name = "b" args = ["/bin/false"] }`, 2076 }, 2077 patch: func(rt *RuntimeConfig) { 2078 rt.Checks = []*structs.CheckDefinition{ 2079 &structs.CheckDefinition{Name: "a", ScriptArgs: []string{"/bin/true"}}, 2080 &structs.CheckDefinition{Name: "b", ScriptArgs: []string{"/bin/false"}}, 2081 } 2082 rt.DataDir = dataDir 2083 }, 2084 }, 2085 { 2086 desc: "grpc check", 2087 args: []string{ 2088 `-data-dir=` + dataDir, 2089 }, 2090 json: []string{ 2091 `{ "check": { "name": "a", "grpc": "localhost:12345/foo", "grpc_use_tls": true } }`, 2092 }, 2093 hcl: []string{ 2094 `check = { name = "a" grpc = "localhost:12345/foo", grpc_use_tls = true }`, 2095 }, 2096 patch: func(rt *RuntimeConfig) { 2097 rt.Checks = []*structs.CheckDefinition{ 2098 &structs.CheckDefinition{Name: "a", GRPC: "localhost:12345/foo", GRPCUseTLS: true}, 2099 } 2100 rt.DataDir = dataDir 2101 }, 2102 }, 2103 { 2104 desc: "alias check with no node", 2105 args: []string{ 2106 `-data-dir=` + dataDir, 2107 }, 2108 json: []string{ 2109 `{ "check": { "name": "a", "alias_service": "foo" } }`, 2110 }, 2111 hcl: []string{ 2112 `check = { name = "a", alias_service = "foo" }`, 2113 }, 2114 patch: func(rt *RuntimeConfig) { 2115 rt.Checks = []*structs.CheckDefinition{ 2116 &structs.CheckDefinition{Name: "a", AliasService: "foo"}, 2117 } 2118 rt.DataDir = dataDir 2119 }, 2120 }, 2121 { 2122 desc: "multiple service files", 2123 args: []string{ 2124 `-data-dir=` + dataDir, 2125 }, 2126 json: []string{ 2127 `{ "service": { "name": "a", "port": 80 } }`, 2128 `{ "service": { "name": "b", "port": 90, "meta": {"my": "value"}, "weights": {"passing": 13} } }`, 2129 }, 2130 hcl: []string{ 2131 `service = { name = "a" port = 80 }`, 2132 `service = { name = "b" port = 90 meta={my="value"}, weights={passing=13}}`, 2133 }, 2134 patch: func(rt *RuntimeConfig) { 2135 rt.Services = []*structs.ServiceDefinition{ 2136 &structs.ServiceDefinition{Name: "a", Port: 80, Weights: &structs.Weights{ 2137 Passing: 1, 2138 Warning: 1, 2139 }}, 2140 &structs.ServiceDefinition{Name: "b", Port: 90, Meta: map[string]string{"my": "value"}, Weights: &structs.Weights{ 2141 Passing: 13, 2142 Warning: 1, 2143 }}, 2144 } 2145 rt.DataDir = dataDir 2146 }, 2147 }, 2148 { 2149 desc: "service with wrong meta: too long key", 2150 args: []string{ 2151 `-data-dir=` + dataDir, 2152 }, 2153 json: []string{ 2154 `{ "service": { "name": "a", "port": 80, "meta": { "` + randomString(520) + `": "metaValue" } } }`, 2155 }, 2156 hcl: []string{ 2157 `service = { name = "a" port = 80, meta={` + randomString(520) + `="metaValue"} }`, 2158 }, 2159 err: `Key is too long`, 2160 }, 2161 { 2162 desc: "service with wrong meta: too long value", 2163 args: []string{ 2164 `-data-dir=` + dataDir, 2165 }, 2166 json: []string{ 2167 `{ "service": { "name": "a", "port": 80, "meta": { "a": "` + randomString(520) + `" } } }`, 2168 }, 2169 hcl: []string{ 2170 `service = { name = "a" port = 80, meta={a="` + randomString(520) + `"} }`, 2171 }, 2172 err: `Value is too long`, 2173 }, 2174 { 2175 desc: "service with wrong meta: too many meta", 2176 args: []string{ 2177 `-data-dir=` + dataDir, 2178 }, 2179 json: []string{ 2180 `{ "service": { "name": "a", "port": 80, "meta": { ` + metaPairs(70, "json") + `} } }`, 2181 }, 2182 hcl: []string{ 2183 `service = { name = "a" port = 80 meta={` + metaPairs(70, "hcl") + `} }`, 2184 }, 2185 err: `invalid meta for service a: Node metadata cannot contain more than 64 key`, 2186 }, 2187 { 2188 desc: "translated keys", 2189 args: []string{ 2190 `-data-dir=` + dataDir, 2191 }, 2192 json: []string{ 2193 `{ 2194 "service": { 2195 "name": "a", 2196 "port": 80, 2197 "enable_tag_override": true, 2198 "check": { 2199 "id": "x", 2200 "name": "y", 2201 "DockerContainerID": "z", 2202 "DeregisterCriticalServiceAfter": "10s", 2203 "ScriptArgs": ["a", "b"] 2204 } 2205 } 2206 }`, 2207 }, 2208 hcl: []string{ 2209 `service = { 2210 name = "a" 2211 port = 80 2212 enable_tag_override = true 2213 check = { 2214 id = "x" 2215 name = "y" 2216 DockerContainerID = "z" 2217 DeregisterCriticalServiceAfter = "10s" 2218 ScriptArgs = ["a", "b"] 2219 } 2220 }`, 2221 }, 2222 patch: func(rt *RuntimeConfig) { 2223 rt.Services = []*structs.ServiceDefinition{ 2224 &structs.ServiceDefinition{ 2225 Name: "a", 2226 Port: 80, 2227 EnableTagOverride: true, 2228 Checks: []*structs.CheckType{ 2229 &structs.CheckType{ 2230 CheckID: types.CheckID("x"), 2231 Name: "y", 2232 DockerContainerID: "z", 2233 DeregisterCriticalServiceAfter: 10 * time.Second, 2234 ScriptArgs: []string{"a", "b"}, 2235 }, 2236 }, 2237 Weights: &structs.Weights{ 2238 Passing: 1, 2239 Warning: 1, 2240 }, 2241 }, 2242 } 2243 rt.DataDir = dataDir 2244 }, 2245 }, 2246 { 2247 desc: "ignore snapshot_agent sub-object", 2248 args: []string{ 2249 `-data-dir=` + dataDir, 2250 }, 2251 json: []string{ 2252 `{ "snapshot_agent": { "dont": "care" } }`, 2253 }, 2254 hcl: []string{ 2255 `snapshot_agent = { dont = "care" }`, 2256 }, 2257 patch: func(rt *RuntimeConfig) { 2258 rt.DataDir = dataDir 2259 }, 2260 }, 2261 2262 { 2263 desc: "Service managed proxy 'upstreams'", 2264 args: []string{ 2265 `-data-dir=` + dataDir, 2266 }, 2267 json: []string{ 2268 `{ 2269 "service": { 2270 "name": "web", 2271 "port": 8080, 2272 "connect": { 2273 "proxy": { 2274 "upstreams": [{ 2275 "destination_name": "db", 2276 "local_bind_port": 1234 2277 }] 2278 } 2279 } 2280 } 2281 }`, 2282 }, 2283 hcl: []string{ 2284 `service { 2285 name = "web" 2286 port = 8080 2287 connect { 2288 proxy { 2289 upstreams { 2290 destination_name = "db" 2291 local_bind_port = 1234 2292 } 2293 } 2294 } 2295 }`, 2296 }, 2297 patch: func(rt *RuntimeConfig) { 2298 rt.DataDir = dataDir 2299 rt.Services = []*structs.ServiceDefinition{ 2300 &structs.ServiceDefinition{ 2301 Name: "web", 2302 Port: 8080, 2303 Connect: &structs.ServiceConnect{ 2304 Proxy: &structs.ServiceDefinitionConnectProxy{ 2305 Upstreams: structs.Upstreams{ 2306 { 2307 DestinationName: "db", 2308 DestinationType: structs.UpstreamDestTypeService, 2309 LocalBindPort: 1234, 2310 }, 2311 }, 2312 }, 2313 }, 2314 Weights: &structs.Weights{ 2315 Passing: 1, 2316 Warning: 1, 2317 }, 2318 }, 2319 } 2320 }, 2321 }, 2322 2323 { 2324 desc: "Multiple service managed proxy 'upstreams'", 2325 args: []string{ 2326 `-data-dir=` + dataDir, 2327 }, 2328 json: []string{ 2329 `{ 2330 "service": { 2331 "name": "web", 2332 "port": 8080, 2333 "connect": { 2334 "proxy": { 2335 "upstreams": [{ 2336 "destination_name": "db", 2337 "local_bind_port": 1234 2338 }, { 2339 "destination_name": "cache", 2340 "local_bind_port": 2345 2341 }] 2342 } 2343 } 2344 } 2345 }`, 2346 }, 2347 hcl: []string{ 2348 `service { 2349 name = "web" 2350 port = 8080 2351 connect { 2352 proxy { 2353 upstreams = [ 2354 { 2355 destination_name = "db" 2356 local_bind_port = 1234 2357 }, 2358 { 2359 destination_name = "cache" 2360 local_bind_port = 2345 2361 } 2362 ] 2363 } 2364 } 2365 }`, 2366 }, 2367 patch: func(rt *RuntimeConfig) { 2368 rt.DataDir = dataDir 2369 rt.Services = []*structs.ServiceDefinition{ 2370 &structs.ServiceDefinition{ 2371 Name: "web", 2372 Port: 8080, 2373 Connect: &structs.ServiceConnect{ 2374 Proxy: &structs.ServiceDefinitionConnectProxy{ 2375 Upstreams: structs.Upstreams{ 2376 { 2377 DestinationName: "db", 2378 DestinationType: structs.UpstreamDestTypeService, 2379 LocalBindPort: 1234, 2380 }, 2381 { 2382 DestinationName: "cache", 2383 DestinationType: structs.UpstreamDestTypeService, 2384 LocalBindPort: 2345, 2385 }, 2386 }, 2387 }, 2388 }, 2389 Weights: &structs.Weights{ 2390 Passing: 1, 2391 Warning: 1, 2392 }, 2393 }, 2394 } 2395 }, 2396 }, 2397 2398 { 2399 desc: "enabling Connect allow_managed_root", 2400 args: []string{ 2401 `-data-dir=` + dataDir, 2402 }, 2403 json: []string{ 2404 `{ "connect": { "proxy": { "allow_managed_root": true } } }`, 2405 }, 2406 hcl: []string{ 2407 `connect { proxy { allow_managed_root = true } }`, 2408 }, 2409 patch: func(rt *RuntimeConfig) { 2410 rt.DataDir = dataDir 2411 rt.ConnectProxyAllowManagedRoot = true 2412 }, 2413 }, 2414 2415 { 2416 desc: "enabling Connect allow_managed_api_registration", 2417 args: []string{ 2418 `-data-dir=` + dataDir, 2419 }, 2420 json: []string{ 2421 `{ "connect": { "proxy": { "allow_managed_api_registration": true } } }`, 2422 }, 2423 hcl: []string{ 2424 `connect { proxy { allow_managed_api_registration = true } }`, 2425 }, 2426 patch: func(rt *RuntimeConfig) { 2427 rt.DataDir = dataDir 2428 rt.ConnectProxyAllowManagedAPIRegistration = true 2429 }, 2430 }, 2431 2432 { 2433 // This tests that we correct added the nested paths to arrays of objects 2434 // to the exceptions in patchSliceOfMaps in config.go (for single service) 2435 desc: "service.connectsidecar_service with checks and upstreams", 2436 args: []string{ 2437 `-data-dir=` + dataDir, 2438 }, 2439 json: []string{`{ 2440 "service": { 2441 "name": "web", 2442 "port": 1234, 2443 "connect": { 2444 "sidecar_service": { 2445 "port": 2345, 2446 "checks": [ 2447 { 2448 "TCP": "127.0.0.1:2345", 2449 "Interval": "10s" 2450 } 2451 ], 2452 "proxy": { 2453 "upstreams": [ 2454 { 2455 "destination_name": "db", 2456 "local_bind_port": 7000 2457 } 2458 ] 2459 } 2460 } 2461 } 2462 } 2463 }`}, 2464 hcl: []string{` 2465 service { 2466 name = "web" 2467 port = 1234 2468 connect { 2469 sidecar_service { 2470 port = 2345 2471 checks = [ 2472 { 2473 tcp = "127.0.0.1:2345" 2474 interval = "10s" 2475 } 2476 ] 2477 proxy { 2478 upstreams = [ 2479 { 2480 destination_name = "db" 2481 local_bind_port = 7000 2482 }, 2483 ] 2484 } 2485 } 2486 } 2487 } 2488 `}, 2489 patch: func(rt *RuntimeConfig) { 2490 rt.DataDir = dataDir 2491 rt.Services = []*structs.ServiceDefinition{ 2492 { 2493 Name: "web", 2494 Port: 1234, 2495 Connect: &structs.ServiceConnect{ 2496 SidecarService: &structs.ServiceDefinition{ 2497 Port: 2345, 2498 Checks: structs.CheckTypes{ 2499 { 2500 TCP: "127.0.0.1:2345", 2501 Interval: 10 * time.Second, 2502 }, 2503 }, 2504 Proxy: &structs.ConnectProxyConfig{ 2505 Upstreams: structs.Upstreams{ 2506 structs.Upstream{ 2507 DestinationType: "service", 2508 DestinationName: "db", 2509 LocalBindPort: 7000, 2510 }, 2511 }, 2512 }, 2513 Weights: &structs.Weights{ 2514 Passing: 1, 2515 Warning: 1, 2516 }, 2517 }, 2518 }, 2519 Weights: &structs.Weights{ 2520 Passing: 1, 2521 Warning: 1, 2522 }, 2523 }, 2524 } 2525 }, 2526 }, 2527 { 2528 // This tests that we correct added the nested paths to arrays of objects 2529 // to the exceptions in patchSliceOfMaps in config.go (for service*s*) 2530 desc: "services.connect.sidecar_service with checks and upstreams", 2531 args: []string{ 2532 `-data-dir=` + dataDir, 2533 }, 2534 json: []string{`{ 2535 "services": [{ 2536 "name": "web", 2537 "port": 1234, 2538 "connect": { 2539 "sidecar_service": { 2540 "port": 2345, 2541 "checks": [ 2542 { 2543 "TCP": "127.0.0.1:2345", 2544 "Interval": "10s" 2545 } 2546 ], 2547 "proxy": { 2548 "upstreams": [ 2549 { 2550 "destination_name": "db", 2551 "local_bind_port": 7000 2552 } 2553 ] 2554 } 2555 } 2556 } 2557 }] 2558 }`}, 2559 hcl: []string{` 2560 services = [{ 2561 name = "web" 2562 port = 1234 2563 connect { 2564 sidecar_service { 2565 port = 2345 2566 checks = [ 2567 { 2568 tcp = "127.0.0.1:2345" 2569 interval = "10s" 2570 } 2571 ] 2572 proxy { 2573 upstreams = [ 2574 { 2575 destination_name = "db" 2576 local_bind_port = 7000 2577 }, 2578 ] 2579 } 2580 } 2581 } 2582 }] 2583 `}, 2584 patch: func(rt *RuntimeConfig) { 2585 rt.DataDir = dataDir 2586 rt.Services = []*structs.ServiceDefinition{ 2587 { 2588 Name: "web", 2589 Port: 1234, 2590 Connect: &structs.ServiceConnect{ 2591 SidecarService: &structs.ServiceDefinition{ 2592 Port: 2345, 2593 Checks: structs.CheckTypes{ 2594 { 2595 TCP: "127.0.0.1:2345", 2596 Interval: 10 * time.Second, 2597 }, 2598 }, 2599 Proxy: &structs.ConnectProxyConfig{ 2600 Upstreams: structs.Upstreams{ 2601 structs.Upstream{ 2602 DestinationType: "service", 2603 DestinationName: "db", 2604 LocalBindPort: 7000, 2605 }, 2606 }, 2607 }, 2608 Weights: &structs.Weights{ 2609 Passing: 1, 2610 Warning: 1, 2611 }, 2612 }, 2613 }, 2614 Weights: &structs.Weights{ 2615 Passing: 1, 2616 Warning: 1, 2617 }, 2618 }, 2619 } 2620 }, 2621 }, 2622 { 2623 // This tests checks that VerifyServerHostname implies VerifyOutgoing 2624 desc: "verify_server_hostname implies verify_outgoing", 2625 args: []string{ 2626 `-data-dir=` + dataDir, 2627 }, 2628 json: []string{`{ 2629 "verify_server_hostname": true 2630 }`}, 2631 hcl: []string{` 2632 verify_server_hostname = true 2633 `}, 2634 patch: func(rt *RuntimeConfig) { 2635 rt.DataDir = dataDir 2636 rt.VerifyServerHostname = true 2637 rt.VerifyOutgoing = true 2638 }, 2639 }, 2640 { 2641 desc: "test connect vault provider configuration", 2642 args: []string{ 2643 `-data-dir=` + dataDir, 2644 }, 2645 json: []string{`{ 2646 "connect": { 2647 "enabled": true, 2648 "ca_provider": "vault", 2649 "ca_config": { 2650 "ca_file": "/capath/ca.pem", 2651 "ca_path": "/capath/", 2652 "cert_file": "/certpath/cert.pem", 2653 "key_file": "/certpath/key.pem", 2654 "tls_server_name": "server.name", 2655 "tls_skip_verify": true, 2656 "token": "abc", 2657 "root_pki_path": "consul-vault", 2658 "intermediate_pki_path": "connect-intermediate" 2659 } 2660 } 2661 }`}, 2662 hcl: []string{` 2663 connect { 2664 enabled = true 2665 ca_provider = "vault" 2666 ca_config { 2667 ca_file = "/capath/ca.pem" 2668 ca_path = "/capath/" 2669 cert_file = "/certpath/cert.pem" 2670 key_file = "/certpath/key.pem" 2671 tls_server_name = "server.name" 2672 tls_skip_verify = true 2673 token = "abc" 2674 root_pki_path = "consul-vault" 2675 intermediate_pki_path = "connect-intermediate" 2676 } 2677 } 2678 `}, 2679 patch: func(rt *RuntimeConfig) { 2680 rt.DataDir = dataDir 2681 rt.ConnectEnabled = true 2682 rt.ConnectCAProvider = "vault" 2683 rt.ConnectCAConfig = map[string]interface{}{ 2684 "CAFile": "/capath/ca.pem", 2685 "CAPath": "/capath/", 2686 "CertFile": "/certpath/cert.pem", 2687 "KeyFile": "/certpath/key.pem", 2688 "TLSServerName": "server.name", 2689 "TLSSkipVerify": true, 2690 "Token": "abc", 2691 "RootPKIPath": "consul-vault", 2692 "IntermediatePKIPath": "connect-intermediate", 2693 } 2694 }, 2695 }, 2696 } 2697 2698 testConfig(t, tests, dataDir) 2699 } 2700 2701 func testConfig(t *testing.T, tests []configTest, dataDir string) { 2702 for _, tt := range tests { 2703 for pass, format := range []string{"json", "hcl"} { 2704 // clean data dir before every test 2705 cleanDir(dataDir) 2706 2707 // when we test only flags then there are no JSON or HCL 2708 // sources and we need to make only one pass over the 2709 // tests. 2710 flagsOnly := len(tt.json) == 0 && len(tt.hcl) == 0 2711 if flagsOnly && pass > 0 { 2712 continue 2713 } 2714 2715 // json and hcl sources need to be in sync 2716 // to make sure we're generating the same config 2717 if len(tt.json) != len(tt.hcl) && !tt.skipformat { 2718 t.Fatal(tt.desc, ": JSON and HCL test case out of sync") 2719 } 2720 2721 // select the source 2722 srcs, tails := tt.json, tt.jsontail 2723 if format == "hcl" { 2724 srcs, tails = tt.hcl, tt.hcltail 2725 } 2726 2727 // If we're skipping a format and the current format is empty, 2728 // then skip it! 2729 if tt.skipformat && len(srcs) == 0 { 2730 continue 2731 } 2732 2733 // build the description 2734 var desc []string 2735 if !flagsOnly { 2736 desc = append(desc, format) 2737 } 2738 if tt.desc != "" { 2739 desc = append(desc, tt.desc) 2740 } 2741 2742 t.Run(strings.Join(desc, ":"), func(t *testing.T) { 2743 // first parse the flags 2744 flags := Flags{} 2745 fs := flag.NewFlagSet("", flag.ContinueOnError) 2746 AddFlags(fs, &flags) 2747 err := fs.Parse(tt.args) 2748 if err != nil { 2749 t.Fatalf("ParseFlags failed: %s", err) 2750 } 2751 flags.Args = fs.Args() 2752 2753 if tt.pre != nil { 2754 tt.pre() 2755 } 2756 defer func() { 2757 if tt.post != nil { 2758 tt.post() 2759 } 2760 }() 2761 2762 // Then create a builder with the flags. 2763 b, err := NewBuilder(flags) 2764 if err != nil { 2765 t.Fatal("NewBuilder", err) 2766 } 2767 2768 // mock the hostname function unless a mock is provided 2769 b.Hostname = tt.hostname 2770 if b.Hostname == nil { 2771 b.Hostname = func() (string, error) { return "nodex", nil } 2772 } 2773 2774 // mock the ip address detection 2775 privatev4 := tt.privatev4 2776 if privatev4 == nil { 2777 privatev4 = func() ([]*net.IPAddr, error) { 2778 return []*net.IPAddr{ipAddr("10.0.0.1")}, nil 2779 } 2780 } 2781 publicv6 := tt.publicv6 2782 if publicv6 == nil { 2783 publicv6 = func() ([]*net.IPAddr, error) { 2784 return []*net.IPAddr{ipAddr("dead:beef::1")}, nil 2785 } 2786 } 2787 b.GetPrivateIPv4 = privatev4 2788 b.GetPublicIPv6 = publicv6 2789 2790 // read the source fragements 2791 for i, data := range srcs { 2792 b.Sources = append(b.Sources, Source{ 2793 Name: fmt.Sprintf("src-%d.%s", i, format), 2794 Format: format, 2795 Data: data, 2796 }) 2797 } 2798 for i, data := range tails { 2799 b.Tail = append(b.Tail, Source{ 2800 Name: fmt.Sprintf("tail-%d.%s", i, format), 2801 Format: format, 2802 Data: data, 2803 }) 2804 } 2805 2806 // build/merge the config fragments 2807 rt, err := b.BuildAndValidate() 2808 if err == nil && tt.err != "" { 2809 t.Fatalf("got no error want %q", tt.err) 2810 } 2811 if err != nil && tt.err == "" { 2812 t.Fatalf("got error %s want nil", err) 2813 } 2814 if err == nil && tt.err != "" { 2815 t.Fatalf("got nil want error to contain %q", tt.err) 2816 } 2817 if err != nil && tt.err != "" && !strings.Contains(err.Error(), tt.err) { 2818 t.Fatalf("error %q does not contain %q", err.Error(), tt.err) 2819 } 2820 2821 // check the warnings 2822 if !verify.Values(t, "warnings", b.Warnings, tt.warns) { 2823 t.FailNow() 2824 } 2825 2826 // stop if we expected an error 2827 if tt.err != "" { 2828 return 2829 } 2830 2831 // build a default configuration, then patch the fields we expect to change 2832 // and compare it with the generated configuration. Since the expected 2833 // runtime config has been validated we do not need to validate it again. 2834 x, err := NewBuilder(Flags{}) 2835 if err != nil { 2836 t.Fatal(err) 2837 } 2838 x.Hostname = b.Hostname 2839 x.GetPrivateIPv4 = func() ([]*net.IPAddr, error) { return []*net.IPAddr{ipAddr("10.0.0.1")}, nil } 2840 x.GetPublicIPv6 = func() ([]*net.IPAddr, error) { return []*net.IPAddr{ipAddr("dead:beef::1")}, nil } 2841 patchedRT, err := x.Build() 2842 if err != nil { 2843 t.Fatalf("build default failed: %s", err) 2844 } 2845 if tt.patch != nil { 2846 tt.patch(&patchedRT) 2847 } 2848 // if err := x.Validate(wantRT); err != nil { 2849 // t.Fatalf("validate default failed: %s", err) 2850 // } 2851 if got, want := rt, patchedRT; !verify.Values(t, "", got, want) { 2852 t.FailNow() 2853 } 2854 }) 2855 } 2856 } 2857 } 2858 2859 // TestFullConfig tests the conversion from a fully populated JSON or 2860 // HCL config file to a RuntimeConfig structure. All fields must be set 2861 // to a unique non-zero value. 2862 // 2863 // To aid populating the fields the following bash functions can be used 2864 // to generate random strings and ints: 2865 // 2866 // random-int() { echo $RANDOM } 2867 // random-string() { base64 /dev/urandom | tr -d '/+' | fold -w ${1:-32} | head -n 1 } 2868 // 2869 // To generate a random string of length 8 run the following command in 2870 // a terminal: 2871 // 2872 // random-string 8 2873 // 2874 func TestFullConfig(t *testing.T) { 2875 dataDir := testutil.TempDir(t, "consul") 2876 defer os.RemoveAll(dataDir) 2877 2878 cidr := func(s string) *net.IPNet { 2879 _, n, _ := net.ParseCIDR(s) 2880 return n 2881 } 2882 2883 flagSrc := []string{`-dev`} 2884 src := map[string]string{ 2885 "json": `{ 2886 "acl_agent_master_token": "furuQD0b", 2887 "acl_agent_token": "cOshLOQ2", 2888 "acl_datacenter": "m3urck3z", 2889 "acl_default_policy": "ArK3WIfE", 2890 "acl_down_policy": "vZXMfMP0", 2891 "acl_enforce_version_8": true, 2892 "acl_enable_key_list_policy": true, 2893 "acl_master_token": "C1Q1oIwh", 2894 "acl_replication_token": "LMmgy5dO", 2895 "acl_token": "O1El0wan", 2896 "acl_ttl": "18060s", 2897 "acl" : { 2898 "enabled" : true, 2899 "down_policy" : "03eb2aee", 2900 "default_policy" : "72c2e7a0", 2901 "enable_key_list_policy": false, 2902 "enable_token_persistence": true, 2903 "policy_ttl": "1123s", 2904 "token_ttl": "3321s", 2905 "enable_token_replication" : true, 2906 "tokens" : { 2907 "master" : "8a19ac27", 2908 "agent_master" : "64fd0e08", 2909 "replication" : "5795983a", 2910 "agent" : "bed2377c", 2911 "default" : "418fdff1" 2912 } 2913 }, 2914 "addresses": { 2915 "dns": "93.95.95.81", 2916 "http": "83.39.91.39", 2917 "https": "95.17.17.19", 2918 "grpc": "32.31.61.91" 2919 }, 2920 "advertise_addr": "17.99.29.16", 2921 "advertise_addr_wan": "78.63.37.19", 2922 "autopilot": { 2923 "cleanup_dead_servers": true, 2924 "disable_upgrade_migration": true, 2925 "last_contact_threshold": "12705s", 2926 "max_trailing_logs": 17849, 2927 "redundancy_zone_tag": "3IsufDJf", 2928 "server_stabilization_time": "23057s", 2929 "upgrade_version_tag": "W9pDwFAL" 2930 }, 2931 "bind_addr": "16.99.34.17", 2932 "bootstrap": true, 2933 "bootstrap_expect": 53, 2934 "ca_file": "erA7T0PM", 2935 "ca_path": "mQEN1Mfp", 2936 "cert_file": "7s4QAzDk", 2937 "check": { 2938 "id": "fZaCAXww", 2939 "name": "OOM2eo0f", 2940 "notes": "zXzXI9Gt", 2941 "service_id": "L8G0QNmR", 2942 "token": "oo4BCTgJ", 2943 "status": "qLykAl5u", 2944 "args": ["f3BemRjy", "e5zgpef7"], 2945 "http": "29B93haH", 2946 "header": { 2947 "hBq0zn1q": [ "2a9o9ZKP", "vKwA5lR6" ], 2948 "f3r6xFtM": [ "RyuIdDWv", "QbxEcIUM" ] 2949 }, 2950 "method": "Dou0nGT5", 2951 "tcp": "JY6fTTcw", 2952 "interval": "18714s", 2953 "docker_container_id": "qF66POS9", 2954 "shell": "sOnDy228", 2955 "tls_skip_verify": true, 2956 "timeout": "5954s", 2957 "ttl": "30044s", 2958 "deregister_critical_service_after": "13209s" 2959 }, 2960 "checks": [ 2961 { 2962 "id": "uAjE6m9Z", 2963 "name": "QsZRGpYr", 2964 "notes": "VJ7Sk4BY", 2965 "service_id": "lSulPcyz", 2966 "token": "toO59sh8", 2967 "status": "9RlWsXMV", 2968 "args": ["4BAJttck", "4D2NPtTQ"], 2969 "http": "dohLcyQ2", 2970 "header": { 2971 "ZBfTin3L": [ "1sDbEqYG", "lJGASsWK" ], 2972 "Ui0nU99X": [ "LMccm3Qe", "k5H5RggQ" ] 2973 }, 2974 "method": "aldrIQ4l", 2975 "tcp": "RJQND605", 2976 "interval": "22164s", 2977 "docker_container_id": "ipgdFtjd", 2978 "shell": "qAeOYy0M", 2979 "tls_skip_verify": true, 2980 "timeout": "1813s", 2981 "ttl": "21743s", 2982 "deregister_critical_service_after": "14232s" 2983 }, 2984 { 2985 "id": "Cqq95BhP", 2986 "name": "3qXpkS0i", 2987 "notes": "sb5qLTex", 2988 "service_id": "CmUUcRna", 2989 "token": "a3nQzHuy", 2990 "status": "irj26nf3", 2991 "args": ["9s526ogY", "gSlOHj1w"], 2992 "http": "yzhgsQ7Y", 2993 "header": { 2994 "zcqwA8dO": [ "qb1zx0DL", "sXCxPFsD" ], 2995 "qxvdnSE9": [ "6wBPUYdF", "YYh8wtSZ" ] 2996 }, 2997 "method": "gLrztrNw", 2998 "tcp": "4jG5casb", 2999 "interval": "28767s", 3000 "docker_container_id": "THW6u7rL", 3001 "shell": "C1Zt3Zwh", 3002 "tls_skip_verify": true, 3003 "timeout": "18506s", 3004 "ttl": "31006s", 3005 "deregister_critical_service_after": "2366s" 3006 } 3007 ], 3008 "check_update_interval": "16507s", 3009 "client_addr": "93.83.18.19", 3010 "connect": { 3011 "ca_provider": "consul", 3012 "ca_config": { 3013 "rotation_period": "90h", 3014 "leaf_cert_ttl": "1h", 3015 "csr_max_per_second": 100, 3016 "csr_max_concurrent": 2 3017 }, 3018 "enabled": true, 3019 "proxy_defaults": { 3020 "exec_mode": "script", 3021 "daemon_command": ["consul", "connect", "proxy"], 3022 "script_command": ["proxyctl.sh"], 3023 "config": { 3024 "foo": "bar", 3025 "connect_timeout_ms": 1000, 3026 "pedantic_mode": true 3027 } 3028 } 3029 }, 3030 "gossip_lan" : { 3031 "gossip_nodes": 6, 3032 "gossip_interval" : "25252s", 3033 "retransmit_mult" : 1234, 3034 "suspicion_mult" : 1235, 3035 "probe_interval" : "101ms", 3036 "probe_timeout" : "102ms" 3037 }, 3038 "gossip_wan" : { 3039 "gossip_nodes" : 2, 3040 "gossip_interval" : "6966s", 3041 "retransmit_mult" : 16384, 3042 "suspicion_mult" : 16385, 3043 "probe_interval" : "103ms", 3044 "probe_timeout" : "104ms" 3045 }, 3046 "data_dir": "` + dataDir + `", 3047 "datacenter": "rzo029wg", 3048 "disable_anonymous_signature": true, 3049 "disable_coordinates": true, 3050 "disable_host_node_id": true, 3051 "disable_http_unprintable_char_filter": true, 3052 "disable_keyring_file": true, 3053 "disable_remote_exec": true, 3054 "disable_update_check": true, 3055 "discard_check_output": true, 3056 "discovery_max_stale": "5s", 3057 "domain": "7W1xXSqd", 3058 "dns_config": { 3059 "allow_stale": true, 3060 "a_record_limit": 29907, 3061 "disable_compression": true, 3062 "enable_truncate": true, 3063 "max_stale": "29685s", 3064 "node_ttl": "7084s", 3065 "only_passing": true, 3066 "recursor_timeout": "4427s", 3067 "service_ttl": { 3068 "*": "32030s" 3069 }, 3070 "udp_answer_limit": 29909, 3071 "use_cache": true, 3072 "cache_max_age": "5m" 3073 }, 3074 "enable_acl_replication": true, 3075 "enable_agent_tls_for_checks": true, 3076 "enable_debug": true, 3077 "enable_script_checks": true, 3078 "enable_local_script_checks": true, 3079 "enable_syslog": true, 3080 "encrypt": "A4wELWqH", 3081 "encrypt_verify_incoming": true, 3082 "encrypt_verify_outgoing": true, 3083 "http_config": { 3084 "block_endpoints": [ "RBvAFcGD", "fWOWFznh" ], 3085 "allow_write_http_from": [ "127.0.0.1/8", "22.33.44.55/32", "0.0.0.0/0" ], 3086 "response_headers": { 3087 "M6TKa9NP": "xjuxjOzQ", 3088 "JRCrHZed": "rl0mTx81" 3089 } 3090 }, 3091 "key_file": "IEkkwgIA", 3092 "leave_on_terminate": true, 3093 "limits": { 3094 "rpc_rate": 12029.43, 3095 "rpc_max_burst": 44848 3096 }, 3097 "log_level": "k1zo9Spt", 3098 "node_id": "AsUIlw99", 3099 "node_meta": { 3100 "5mgGQMBk": "mJLtVMSG", 3101 "A7ynFMJB": "0Nx6RGab" 3102 }, 3103 "node_name": "otlLxGaI", 3104 "non_voting_server": true, 3105 "performance": { 3106 "leave_drain_time": "8265s", 3107 "raft_multiplier": 5, 3108 "rpc_hold_timeout": "15707s" 3109 }, 3110 "pid_file": "43xN80Km", 3111 "ports": { 3112 "dns": 7001, 3113 "http": 7999, 3114 "https": 15127, 3115 "server": 3757, 3116 "grpc": 4881, 3117 "proxy_min_port": 2000, 3118 "proxy_max_port": 3000, 3119 "sidecar_min_port": 8888, 3120 "sidecar_max_port": 9999 3121 }, 3122 "protocol": 30793, 3123 "primary_datacenter": "ejtmd43d", 3124 "raft_protocol": 19016, 3125 "raft_snapshot_threshold": 16384, 3126 "raft_snapshot_interval": "30s", 3127 "reconnect_timeout": "23739s", 3128 "reconnect_timeout_wan": "26694s", 3129 "recursors": [ "63.38.39.58", "92.49.18.18" ], 3130 "rejoin_after_leave": true, 3131 "retry_interval": "8067s", 3132 "retry_interval_wan": "28866s", 3133 "retry_join": [ "pbsSFY7U", "l0qLtWij" ], 3134 "retry_join_wan": [ "PFsR02Ye", "rJdQIhER" ], 3135 "retry_max": 913, 3136 "retry_max_wan": 23160, 3137 "segment": "BC2NhTDi", 3138 "segments": [ 3139 { 3140 "name": "PExYMe2E", 3141 "bind": "36.73.36.19", 3142 "port": 38295, 3143 "rpc_listener": true, 3144 "advertise": "63.39.19.18" 3145 }, 3146 { 3147 "name": "UzCvJgup", 3148 "bind": "37.58.38.19", 3149 "port": 39292, 3150 "rpc_listener": true, 3151 "advertise": "83.58.26.27" 3152 } 3153 ], 3154 "serf_lan": "99.43.63.15", 3155 "serf_wan": "67.88.33.19", 3156 "server": true, 3157 "server_name": "Oerr9n1G", 3158 "service": { 3159 "id": "dLOXpSCI", 3160 "name": "o1ynPkp0", 3161 "meta": { 3162 "mymeta": "data" 3163 }, 3164 "tags": ["nkwshvM5", "NTDWn3ek"], 3165 "address": "cOlSOhbp", 3166 "token": "msy7iWER", 3167 "port": 24237, 3168 "weights": { 3169 "passing": 100, 3170 "warning": 1 3171 }, 3172 "enable_tag_override": true, 3173 "check": { 3174 "id": "RMi85Dv8", 3175 "name": "iehanzuq", 3176 "status": "rCvn53TH", 3177 "notes": "fti5lfF3", 3178 "args": ["16WRUmwS", "QWk7j7ae"], 3179 "http": "dl3Fgme3", 3180 "header": { 3181 "rjm4DEd3": ["2m3m2Fls"], 3182 "l4HwQ112": ["fk56MNlo", "dhLK56aZ"] 3183 }, 3184 "method": "9afLm3Mj", 3185 "tcp": "fjiLFqVd", 3186 "interval": "23926s", 3187 "docker_container_id": "dO5TtRHk", 3188 "shell": "e6q2ttES", 3189 "tls_skip_verify": true, 3190 "timeout": "38483s", 3191 "ttl": "10943s", 3192 "deregister_critical_service_after": "68787s" 3193 }, 3194 "checks": [ 3195 { 3196 "id": "Zv99e9Ka", 3197 "name": "sgV4F7Pk", 3198 "notes": "yP5nKbW0", 3199 "status": "7oLMEyfu", 3200 "args": ["5wEZtZpv", "0Ihyk8cS"], 3201 "http": "KyDjGY9H", 3202 "header": { 3203 "gv5qefTz": [ "5Olo2pMG", "PvvKWQU5" ], 3204 "SHOVq1Vv": [ "jntFhyym", "GYJh32pp" ] 3205 }, 3206 "method": "T66MFBfR", 3207 "tcp": "bNnNfx2A", 3208 "interval": "22224s", 3209 "docker_container_id": "ipgdFtjd", 3210 "shell": "omVZq7Sz", 3211 "tls_skip_verify": true, 3212 "timeout": "18913s", 3213 "ttl": "44743s", 3214 "deregister_critical_service_after": "8482s" 3215 }, 3216 { 3217 "id": "G79O6Mpr", 3218 "name": "IEqrzrsd", 3219 "notes": "SVqApqeM", 3220 "status": "XXkVoZXt", 3221 "args": ["wD05Bvao", "rLYB7kQC"], 3222 "http": "kyICZsn8", 3223 "header": { 3224 "4ebP5vL4": [ "G20SrL5Q", "DwPKlMbo" ], 3225 "p2UI34Qz": [ "UsG1D0Qh", "NHhRiB6s" ] 3226 }, 3227 "method": "ciYHWors", 3228 "tcp": "FfvCwlqH", 3229 "interval": "12356s", 3230 "docker_container_id": "HBndBU6R", 3231 "shell": "hVI33JjA", 3232 "tls_skip_verify": true, 3233 "timeout": "38282s", 3234 "ttl": "1181s", 3235 "deregister_critical_service_after": "4992s" 3236 } 3237 ], 3238 "connect": { 3239 "native": true 3240 } 3241 }, 3242 "services": [ 3243 { 3244 "id": "wI1dzxS4", 3245 "name": "7IszXMQ1", 3246 "tags": ["0Zwg8l6v", "zebELdN5"], 3247 "address": "9RhqPSPB", 3248 "token": "myjKJkWH", 3249 "port": 72219, 3250 "enable_tag_override": true, 3251 "check": { 3252 "id": "qmfeO5if", 3253 "name": "atDGP7n5", 3254 "status": "pDQKEhWL", 3255 "notes": "Yt8EDLev", 3256 "args": ["81EDZLPa", "bPY5X8xd"], 3257 "http": "qzHYvmJO", 3258 "header": { 3259 "UkpmZ3a3": ["2dfzXuxZ"], 3260 "cVFpko4u": ["gGqdEB6k", "9LsRo22u"] 3261 }, 3262 "method": "X5DrovFc", 3263 "tcp": "ICbxkpSF", 3264 "interval": "24392s", 3265 "docker_container_id": "ZKXr68Yb", 3266 "shell": "CEfzx0Fo", 3267 "tls_skip_verify": true, 3268 "timeout": "38333s", 3269 "ttl": "57201s", 3270 "deregister_critical_service_after": "44214s" 3271 }, 3272 "connect": { 3273 "sidecar_service": {} 3274 } 3275 }, 3276 { 3277 "id": "MRHVMZuD", 3278 "name": "6L6BVfgH", 3279 "tags": ["7Ale4y6o", "PMBW08hy"], 3280 "address": "R6H6g8h0", 3281 "token": "ZgY8gjMI", 3282 "port": 38292, 3283 "weights": { 3284 "passing": 1979, 3285 "warning": 6 3286 }, 3287 "enable_tag_override": true, 3288 "checks": [ 3289 { 3290 "id": "GTti9hCo", 3291 "name": "9OOS93ne", 3292 "notes": "CQy86DH0", 3293 "status": "P0SWDvrk", 3294 "args": ["EXvkYIuG", "BATOyt6h"], 3295 "http": "u97ByEiW", 3296 "header": { 3297 "MUlReo8L": [ "AUZG7wHG", "gsN0Dc2N" ], 3298 "1UJXjVrT": [ "OJgxzTfk", "xZZrFsq7" ] 3299 }, 3300 "method": "5wkAxCUE", 3301 "tcp": "MN3oA9D2", 3302 "interval": "32718s", 3303 "docker_container_id": "cU15LMet", 3304 "shell": "nEz9qz2l", 3305 "tls_skip_verify": true, 3306 "timeout": "34738s", 3307 "ttl": "22773s", 3308 "deregister_critical_service_after": "84282s" 3309 }, 3310 { 3311 "id": "UHsDeLxG", 3312 "name": "PQSaPWlT", 3313 "notes": "jKChDOdl", 3314 "status": "5qFz6OZn", 3315 "args": ["NMtYWlT9", "vj74JXsm"], 3316 "http": "1LBDJhw4", 3317 "header": { 3318 "cXPmnv1M": [ "imDqfaBx", "NFxZ1bQe" ], 3319 "vr7wY7CS": [ "EtCoNPPL", "9vAarJ5s" ] 3320 }, 3321 "method": "wzByP903", 3322 "tcp": "2exjZIGE", 3323 "interval": "5656s", 3324 "docker_container_id": "5tDBWpfA", 3325 "shell": "rlTpLM8s", 3326 "tls_skip_verify": true, 3327 "timeout": "4868s", 3328 "ttl": "11222s", 3329 "deregister_critical_service_after": "68482s" 3330 } 3331 ], 3332 "connect": { 3333 "proxy": { 3334 "exec_mode": "daemon", 3335 "command": ["awesome-proxy"], 3336 "config": { 3337 "foo": "qux" 3338 } 3339 } 3340 } 3341 }, 3342 { 3343 "id": "Kh81CPF6", 3344 "kind": "connect-proxy", 3345 "name": "Kh81CPF6-proxy", 3346 "port": 31471, 3347 "proxy": { 3348 "config": { 3349 "cedGGtZf": "pWrUNiWw" 3350 }, 3351 "destination_service_id": "6L6BVfgH-id", 3352 "destination_service_name": "6L6BVfgH", 3353 "local_service_address": "127.0.0.2", 3354 "local_service_port": 23759, 3355 "upstreams": [ 3356 { 3357 "destination_name": "KPtAj2cb", 3358 "local_bind_port": 4051, 3359 "config": { 3360 "kzRnZOyd": "nUNKoL8H" 3361 } 3362 }, 3363 { 3364 "destination_name": "KSd8HsRl", 3365 "destination_namespace": "9nakw0td", 3366 "destination_type": "prepared_query", 3367 "local_bind_address": "127.24.88.0", 3368 "local_bind_port": 11884 3369 } 3370 ] 3371 } 3372 } 3373 ], 3374 "session_ttl_min": "26627s", 3375 "skip_leave_on_interrupt": true, 3376 "start_join": [ "LR3hGDoG", "MwVpZ4Up" ], 3377 "start_join_wan": [ "EbFSc3nA", "kwXTh623" ], 3378 "syslog_facility": "hHv79Uia", 3379 "tagged_addresses": { 3380 "7MYgHrYH": "dALJAhLD", 3381 "h6DdBy6K": "ebrr9zZ8" 3382 }, 3383 "telemetry": { 3384 "circonus_api_app": "p4QOTe9j", 3385 "circonus_api_token": "E3j35V23", 3386 "circonus_api_url": "mEMjHpGg", 3387 "circonus_broker_id": "BHlxUhed", 3388 "circonus_broker_select_tag": "13xy1gHm", 3389 "circonus_check_display_name": "DRSlQR6n", 3390 "circonus_check_force_metric_activation": "Ua5FGVYf", 3391 "circonus_check_id": "kGorutad", 3392 "circonus_check_instance_id": "rwoOL6R4", 3393 "circonus_check_search_tag": "ovT4hT4f", 3394 "circonus_check_tags": "prvO4uBl", 3395 "circonus_submission_interval": "DolzaflP", 3396 "circonus_submission_url": "gTcbS93G", 3397 "disable_hostname": true, 3398 "dogstatsd_addr": "0wSndumK", 3399 "dogstatsd_tags": [ "3N81zSUB","Xtj8AnXZ" ], 3400 "filter_default": true, 3401 "prefix_filter": [ "+oJotS8XJ","-cazlEhGn" ], 3402 "metrics_prefix": "ftO6DySn", 3403 "prometheus_retention_time": "15s", 3404 "statsd_address": "drce87cy", 3405 "statsite_address": "HpFwKB8R" 3406 }, 3407 "tls_cipher_suites": "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 3408 "tls_min_version": "pAOWafkR", 3409 "tls_prefer_server_cipher_suites": true, 3410 "translate_wan_addrs": true, 3411 "ui": true, 3412 "ui_dir": "11IFzAUn", 3413 "unix_sockets": { 3414 "group": "8pFodrV8", 3415 "mode": "E8sAwOv4", 3416 "user": "E0nB1DwA" 3417 }, 3418 "verify_incoming": true, 3419 "verify_incoming_https": true, 3420 "verify_incoming_rpc": true, 3421 "verify_outgoing": true, 3422 "verify_server_hostname": true, 3423 "watches": [ 3424 { 3425 "type": "key", 3426 "datacenter": "GyE6jpeW", 3427 "key": "j9lF1Tve", 3428 "handler": "90N7S4LN" 3429 }, { 3430 "type": "keyprefix", 3431 "datacenter": "fYrl3F5d", 3432 "key": "sl3Dffu7", 3433 "args": ["dltjDJ2a", "flEa7C2d"] 3434 } 3435 ] 3436 }`, 3437 "hcl": ` 3438 acl_agent_master_token = "furuQD0b" 3439 acl_agent_token = "cOshLOQ2" 3440 acl_datacenter = "m3urck3z" 3441 acl_default_policy = "ArK3WIfE" 3442 acl_down_policy = "vZXMfMP0" 3443 acl_enforce_version_8 = true 3444 acl_enable_key_list_policy = true 3445 acl_master_token = "C1Q1oIwh" 3446 acl_replication_token = "LMmgy5dO" 3447 acl_token = "O1El0wan" 3448 acl_ttl = "18060s" 3449 acl = { 3450 enabled = true 3451 down_policy = "03eb2aee" 3452 default_policy = "72c2e7a0" 3453 enable_key_list_policy = false 3454 enable_token_persistence = true 3455 policy_ttl = "1123s" 3456 token_ttl = "3321s" 3457 enable_token_replication = true 3458 tokens = { 3459 master = "8a19ac27", 3460 agent_master = "64fd0e08", 3461 replication = "5795983a", 3462 agent = "bed2377c", 3463 default = "418fdff1" 3464 } 3465 } 3466 addresses = { 3467 dns = "93.95.95.81" 3468 http = "83.39.91.39" 3469 https = "95.17.17.19" 3470 grpc = "32.31.61.91" 3471 } 3472 advertise_addr = "17.99.29.16" 3473 advertise_addr_wan = "78.63.37.19" 3474 autopilot = { 3475 cleanup_dead_servers = true 3476 disable_upgrade_migration = true 3477 last_contact_threshold = "12705s" 3478 max_trailing_logs = 17849 3479 redundancy_zone_tag = "3IsufDJf" 3480 server_stabilization_time = "23057s" 3481 upgrade_version_tag = "W9pDwFAL" 3482 } 3483 bind_addr = "16.99.34.17" 3484 bootstrap = true 3485 bootstrap_expect = 53 3486 ca_file = "erA7T0PM" 3487 ca_path = "mQEN1Mfp" 3488 cert_file = "7s4QAzDk" 3489 check = { 3490 id = "fZaCAXww" 3491 name = "OOM2eo0f" 3492 notes = "zXzXI9Gt" 3493 service_id = "L8G0QNmR" 3494 token = "oo4BCTgJ" 3495 status = "qLykAl5u" 3496 args = ["f3BemRjy", "e5zgpef7"] 3497 http = "29B93haH" 3498 header = { 3499 hBq0zn1q = [ "2a9o9ZKP", "vKwA5lR6" ] 3500 f3r6xFtM = [ "RyuIdDWv", "QbxEcIUM" ] 3501 } 3502 method = "Dou0nGT5" 3503 tcp = "JY6fTTcw" 3504 interval = "18714s" 3505 docker_container_id = "qF66POS9" 3506 shell = "sOnDy228" 3507 tls_skip_verify = true 3508 timeout = "5954s" 3509 ttl = "30044s" 3510 deregister_critical_service_after = "13209s" 3511 }, 3512 checks = [ 3513 { 3514 id = "uAjE6m9Z" 3515 name = "QsZRGpYr" 3516 notes = "VJ7Sk4BY" 3517 service_id = "lSulPcyz" 3518 token = "toO59sh8" 3519 status = "9RlWsXMV" 3520 args = ["4BAJttck", "4D2NPtTQ"] 3521 http = "dohLcyQ2" 3522 header = { 3523 "ZBfTin3L" = [ "1sDbEqYG", "lJGASsWK" ] 3524 "Ui0nU99X" = [ "LMccm3Qe", "k5H5RggQ" ] 3525 } 3526 method = "aldrIQ4l" 3527 tcp = "RJQND605" 3528 interval = "22164s" 3529 docker_container_id = "ipgdFtjd" 3530 shell = "qAeOYy0M" 3531 tls_skip_verify = true 3532 timeout = "1813s" 3533 ttl = "21743s" 3534 deregister_critical_service_after = "14232s" 3535 }, 3536 { 3537 id = "Cqq95BhP" 3538 name = "3qXpkS0i" 3539 notes = "sb5qLTex" 3540 service_id = "CmUUcRna" 3541 token = "a3nQzHuy" 3542 status = "irj26nf3" 3543 args = ["9s526ogY", "gSlOHj1w"] 3544 http = "yzhgsQ7Y" 3545 header = { 3546 "zcqwA8dO" = [ "qb1zx0DL", "sXCxPFsD" ] 3547 "qxvdnSE9" = [ "6wBPUYdF", "YYh8wtSZ" ] 3548 } 3549 method = "gLrztrNw" 3550 tcp = "4jG5casb" 3551 interval = "28767s" 3552 docker_container_id = "THW6u7rL" 3553 shell = "C1Zt3Zwh" 3554 tls_skip_verify = true 3555 timeout = "18506s" 3556 ttl = "31006s" 3557 deregister_critical_service_after = "2366s" 3558 } 3559 ] 3560 check_update_interval = "16507s" 3561 client_addr = "93.83.18.19" 3562 connect { 3563 ca_provider = "consul" 3564 ca_config { 3565 rotation_period = "90h" 3566 leaf_cert_ttl = "1h" 3567 # hack float since json parses numbers as float and we have to 3568 # assert against the same thing 3569 csr_max_per_second = 100.0 3570 csr_max_concurrent = 2.0 3571 } 3572 enabled = true 3573 proxy_defaults { 3574 exec_mode = "script" 3575 daemon_command = ["consul", "connect", "proxy"] 3576 script_command = ["proxyctl.sh"] 3577 config = { 3578 foo = "bar" 3579 # hack float since json parses numbers as float and we have to 3580 # assert against the same thing 3581 connect_timeout_ms = 1000.0 3582 pedantic_mode = true 3583 } 3584 } 3585 } 3586 gossip_lan { 3587 gossip_nodes = 6 3588 gossip_interval = "25252s" 3589 retransmit_mult = 1234 3590 suspicion_mult = 1235 3591 probe_interval = "101ms" 3592 probe_timeout = "102ms" 3593 } 3594 gossip_wan { 3595 gossip_nodes = 2 3596 gossip_interval = "6966s" 3597 retransmit_mult = 16384 3598 suspicion_mult = 16385 3599 probe_interval = "103ms" 3600 probe_timeout = "104ms" 3601 } 3602 data_dir = "` + dataDir + `" 3603 datacenter = "rzo029wg" 3604 disable_anonymous_signature = true 3605 disable_coordinates = true 3606 disable_host_node_id = true 3607 disable_http_unprintable_char_filter = true 3608 disable_keyring_file = true 3609 disable_remote_exec = true 3610 disable_update_check = true 3611 discard_check_output = true 3612 discovery_max_stale = "5s" 3613 domain = "7W1xXSqd" 3614 dns_config { 3615 allow_stale = true 3616 a_record_limit = 29907 3617 disable_compression = true 3618 enable_truncate = true 3619 max_stale = "29685s" 3620 node_ttl = "7084s" 3621 only_passing = true 3622 recursor_timeout = "4427s" 3623 service_ttl = { 3624 "*" = "32030s" 3625 } 3626 udp_answer_limit = 29909 3627 use_cache = true 3628 cache_max_age = "5m" 3629 } 3630 enable_acl_replication = true 3631 enable_agent_tls_for_checks = true 3632 enable_debug = true 3633 enable_script_checks = true 3634 enable_local_script_checks = true 3635 enable_syslog = true 3636 encrypt = "A4wELWqH" 3637 encrypt_verify_incoming = true 3638 encrypt_verify_outgoing = true 3639 http_config { 3640 block_endpoints = [ "RBvAFcGD", "fWOWFznh" ] 3641 allow_write_http_from = [ "127.0.0.1/8", "22.33.44.55/32", "0.0.0.0/0" ] 3642 response_headers = { 3643 "M6TKa9NP" = "xjuxjOzQ" 3644 "JRCrHZed" = "rl0mTx81" 3645 } 3646 } 3647 key_file = "IEkkwgIA" 3648 leave_on_terminate = true 3649 limits { 3650 rpc_rate = 12029.43 3651 rpc_max_burst = 44848 3652 } 3653 log_level = "k1zo9Spt" 3654 node_id = "AsUIlw99" 3655 node_meta { 3656 "5mgGQMBk" = "mJLtVMSG" 3657 "A7ynFMJB" = "0Nx6RGab" 3658 } 3659 node_name = "otlLxGaI" 3660 non_voting_server = true 3661 performance { 3662 leave_drain_time = "8265s" 3663 raft_multiplier = 5 3664 rpc_hold_timeout = "15707s" 3665 } 3666 pid_file = "43xN80Km" 3667 ports { 3668 dns = 7001, 3669 http = 7999, 3670 https = 15127 3671 server = 3757 3672 grpc = 4881 3673 proxy_min_port = 2000 3674 proxy_max_port = 3000 3675 sidecar_min_port = 8888 3676 sidecar_max_port = 9999 3677 } 3678 protocol = 30793 3679 primary_datacenter = "ejtmd43d" 3680 raft_protocol = 19016 3681 raft_snapshot_threshold = 16384 3682 raft_snapshot_interval = "30s" 3683 reconnect_timeout = "23739s" 3684 reconnect_timeout_wan = "26694s" 3685 recursors = [ "63.38.39.58", "92.49.18.18" ] 3686 rejoin_after_leave = true 3687 retry_interval = "8067s" 3688 retry_interval_wan = "28866s" 3689 retry_join = [ "pbsSFY7U", "l0qLtWij" ] 3690 retry_join_wan = [ "PFsR02Ye", "rJdQIhER" ] 3691 retry_max = 913 3692 retry_max_wan = 23160 3693 segment = "BC2NhTDi" 3694 segments = [ 3695 { 3696 name = "PExYMe2E" 3697 bind = "36.73.36.19" 3698 port = 38295 3699 rpc_listener = true 3700 advertise = "63.39.19.18" 3701 }, 3702 { 3703 name = "UzCvJgup" 3704 bind = "37.58.38.19" 3705 port = 39292 3706 rpc_listener = true 3707 advertise = "83.58.26.27" 3708 } 3709 ] 3710 serf_lan = "99.43.63.15" 3711 serf_wan = "67.88.33.19" 3712 server = true 3713 server_name = "Oerr9n1G" 3714 service = { 3715 id = "dLOXpSCI" 3716 name = "o1ynPkp0" 3717 meta = { 3718 mymeta = "data" 3719 } 3720 tags = ["nkwshvM5", "NTDWn3ek"] 3721 address = "cOlSOhbp" 3722 token = "msy7iWER" 3723 port = 24237 3724 weights = { 3725 passing = 100, 3726 warning = 1 3727 } 3728 enable_tag_override = true 3729 check = { 3730 id = "RMi85Dv8" 3731 name = "iehanzuq" 3732 status = "rCvn53TH" 3733 notes = "fti5lfF3" 3734 args = ["16WRUmwS", "QWk7j7ae"] 3735 http = "dl3Fgme3" 3736 header = { 3737 rjm4DEd3 = [ "2m3m2Fls" ] 3738 l4HwQ112 = [ "fk56MNlo", "dhLK56aZ" ] 3739 } 3740 method = "9afLm3Mj" 3741 tcp = "fjiLFqVd" 3742 interval = "23926s" 3743 docker_container_id = "dO5TtRHk" 3744 shell = "e6q2ttES" 3745 tls_skip_verify = true 3746 timeout = "38483s" 3747 ttl = "10943s" 3748 deregister_critical_service_after = "68787s" 3749 } 3750 checks = [ 3751 { 3752 id = "Zv99e9Ka" 3753 name = "sgV4F7Pk" 3754 notes = "yP5nKbW0" 3755 status = "7oLMEyfu" 3756 args = ["5wEZtZpv", "0Ihyk8cS"] 3757 http = "KyDjGY9H" 3758 header = { 3759 "gv5qefTz" = [ "5Olo2pMG", "PvvKWQU5" ] 3760 "SHOVq1Vv" = [ "jntFhyym", "GYJh32pp" ] 3761 } 3762 method = "T66MFBfR" 3763 tcp = "bNnNfx2A" 3764 interval = "22224s" 3765 docker_container_id = "ipgdFtjd" 3766 shell = "omVZq7Sz" 3767 tls_skip_verify = true 3768 timeout = "18913s" 3769 ttl = "44743s" 3770 deregister_critical_service_after = "8482s" 3771 }, 3772 { 3773 id = "G79O6Mpr" 3774 name = "IEqrzrsd" 3775 notes = "SVqApqeM" 3776 status = "XXkVoZXt" 3777 args = ["wD05Bvao", "rLYB7kQC"] 3778 http = "kyICZsn8" 3779 header = { 3780 "4ebP5vL4" = [ "G20SrL5Q", "DwPKlMbo" ] 3781 "p2UI34Qz" = [ "UsG1D0Qh", "NHhRiB6s" ] 3782 } 3783 method = "ciYHWors" 3784 tcp = "FfvCwlqH" 3785 interval = "12356s" 3786 docker_container_id = "HBndBU6R" 3787 shell = "hVI33JjA" 3788 tls_skip_verify = true 3789 timeout = "38282s" 3790 ttl = "1181s" 3791 deregister_critical_service_after = "4992s" 3792 } 3793 ] 3794 connect { 3795 native = true 3796 } 3797 } 3798 services = [ 3799 { 3800 id = "wI1dzxS4" 3801 name = "7IszXMQ1" 3802 tags = ["0Zwg8l6v", "zebELdN5"] 3803 address = "9RhqPSPB" 3804 token = "myjKJkWH" 3805 port = 72219 3806 enable_tag_override = true 3807 check = { 3808 id = "qmfeO5if" 3809 name = "atDGP7n5" 3810 status = "pDQKEhWL" 3811 notes = "Yt8EDLev" 3812 args = ["81EDZLPa", "bPY5X8xd"] 3813 http = "qzHYvmJO" 3814 header = { 3815 UkpmZ3a3 = [ "2dfzXuxZ" ] 3816 cVFpko4u = [ "gGqdEB6k", "9LsRo22u" ] 3817 } 3818 method = "X5DrovFc" 3819 tcp = "ICbxkpSF" 3820 interval = "24392s" 3821 docker_container_id = "ZKXr68Yb" 3822 shell = "CEfzx0Fo" 3823 tls_skip_verify = true 3824 timeout = "38333s" 3825 ttl = "57201s" 3826 deregister_critical_service_after = "44214s" 3827 } 3828 connect { 3829 sidecar_service {} 3830 } 3831 }, 3832 { 3833 id = "MRHVMZuD" 3834 name = "6L6BVfgH" 3835 tags = ["7Ale4y6o", "PMBW08hy"] 3836 address = "R6H6g8h0" 3837 token = "ZgY8gjMI" 3838 port = 38292 3839 weights = { 3840 passing = 1979, 3841 warning = 6 3842 } 3843 enable_tag_override = true 3844 checks = [ 3845 { 3846 id = "GTti9hCo" 3847 name = "9OOS93ne" 3848 notes = "CQy86DH0" 3849 status = "P0SWDvrk" 3850 args = ["EXvkYIuG", "BATOyt6h"] 3851 http = "u97ByEiW" 3852 header = { 3853 "MUlReo8L" = [ "AUZG7wHG", "gsN0Dc2N" ] 3854 "1UJXjVrT" = [ "OJgxzTfk", "xZZrFsq7" ] 3855 } 3856 method = "5wkAxCUE" 3857 tcp = "MN3oA9D2" 3858 interval = "32718s" 3859 docker_container_id = "cU15LMet" 3860 shell = "nEz9qz2l" 3861 tls_skip_verify = true 3862 timeout = "34738s" 3863 ttl = "22773s" 3864 deregister_critical_service_after = "84282s" 3865 }, 3866 { 3867 id = "UHsDeLxG" 3868 name = "PQSaPWlT" 3869 notes = "jKChDOdl" 3870 status = "5qFz6OZn" 3871 args = ["NMtYWlT9", "vj74JXsm"] 3872 http = "1LBDJhw4" 3873 header = { 3874 "cXPmnv1M" = [ "imDqfaBx", "NFxZ1bQe" ], 3875 "vr7wY7CS" = [ "EtCoNPPL", "9vAarJ5s" ] 3876 } 3877 method = "wzByP903" 3878 tcp = "2exjZIGE" 3879 interval = "5656s" 3880 docker_container_id = "5tDBWpfA" 3881 shell = "rlTpLM8s" 3882 tls_skip_verify = true 3883 timeout = "4868s" 3884 ttl = "11222s" 3885 deregister_critical_service_after = "68482s" 3886 } 3887 ] 3888 connect { 3889 proxy { 3890 exec_mode = "daemon" 3891 command = ["awesome-proxy"] 3892 config = { 3893 foo = "qux" 3894 } 3895 } 3896 } 3897 }, 3898 { 3899 id = "Kh81CPF6" 3900 name = "Kh81CPF6-proxy" 3901 port = 31471 3902 kind = "connect-proxy" 3903 proxy { 3904 destination_service_name = "6L6BVfgH" 3905 destination_service_id = "6L6BVfgH-id" 3906 local_service_address = "127.0.0.2" 3907 local_service_port = 23759 3908 config { 3909 cedGGtZf = "pWrUNiWw" 3910 } 3911 upstreams = [ 3912 { 3913 destination_name = "KPtAj2cb" 3914 local_bind_port = 4051 3915 config { 3916 kzRnZOyd = "nUNKoL8H" 3917 } 3918 }, 3919 { 3920 destination_type = "prepared_query" 3921 destination_namespace = "9nakw0td" 3922 destination_name = "KSd8HsRl" 3923 local_bind_port = 11884 3924 local_bind_address = "127.24.88.0" 3925 }, 3926 ] 3927 } 3928 } 3929 ] 3930 session_ttl_min = "26627s" 3931 skip_leave_on_interrupt = true 3932 start_join = [ "LR3hGDoG", "MwVpZ4Up" ] 3933 start_join_wan = [ "EbFSc3nA", "kwXTh623" ] 3934 syslog_facility = "hHv79Uia" 3935 tagged_addresses = { 3936 "7MYgHrYH" = "dALJAhLD" 3937 "h6DdBy6K" = "ebrr9zZ8" 3938 } 3939 telemetry { 3940 circonus_api_app = "p4QOTe9j" 3941 circonus_api_token = "E3j35V23" 3942 circonus_api_url = "mEMjHpGg" 3943 circonus_broker_id = "BHlxUhed" 3944 circonus_broker_select_tag = "13xy1gHm" 3945 circonus_check_display_name = "DRSlQR6n" 3946 circonus_check_force_metric_activation = "Ua5FGVYf" 3947 circonus_check_id = "kGorutad" 3948 circonus_check_instance_id = "rwoOL6R4" 3949 circonus_check_search_tag = "ovT4hT4f" 3950 circonus_check_tags = "prvO4uBl" 3951 circonus_submission_interval = "DolzaflP" 3952 circonus_submission_url = "gTcbS93G" 3953 disable_hostname = true 3954 dogstatsd_addr = "0wSndumK" 3955 dogstatsd_tags = [ "3N81zSUB","Xtj8AnXZ" ] 3956 filter_default = true 3957 prefix_filter = [ "+oJotS8XJ","-cazlEhGn" ] 3958 metrics_prefix = "ftO6DySn" 3959 prometheus_retention_time = "15s" 3960 statsd_address = "drce87cy" 3961 statsite_address = "HpFwKB8R" 3962 } 3963 tls_cipher_suites = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" 3964 tls_min_version = "pAOWafkR" 3965 tls_prefer_server_cipher_suites = true 3966 translate_wan_addrs = true 3967 ui = true 3968 ui_dir = "11IFzAUn" 3969 unix_sockets = { 3970 group = "8pFodrV8" 3971 mode = "E8sAwOv4" 3972 user = "E0nB1DwA" 3973 } 3974 verify_incoming = true 3975 verify_incoming_https = true 3976 verify_incoming_rpc = true 3977 verify_outgoing = true 3978 verify_server_hostname = true 3979 watches = [{ 3980 type = "key" 3981 datacenter = "GyE6jpeW" 3982 key = "j9lF1Tve" 3983 handler = "90N7S4LN" 3984 }, { 3985 type = "keyprefix" 3986 datacenter = "fYrl3F5d" 3987 key = "sl3Dffu7" 3988 args = ["dltjDJ2a", "flEa7C2d"] 3989 }] 3990 `} 3991 3992 tail := map[string][]Source{ 3993 "json": []Source{ 3994 { 3995 Name: "tail.non-user.json", 3996 Format: "json", 3997 Data: ` 3998 { 3999 "acl_disabled_ttl": "957s", 4000 "acl" : { 4001 "disabled_ttl" : "957s" 4002 }, 4003 "ae_interval": "10003s", 4004 "check_deregister_interval_min": "27870s", 4005 "check_reap_interval": "10662s", 4006 "discovery_max_stale": "5s", 4007 "segment_limit": 24705, 4008 "segment_name_limit": 27046, 4009 "sync_coordinate_interval_min": "27983s", 4010 "sync_coordinate_rate_target": 137.81 4011 }`, 4012 }, 4013 { 4014 Name: "tail.consul.json", 4015 Format: "json", 4016 Data: ` 4017 { 4018 "consul": { 4019 "coordinate": { 4020 "update_batch_size": 9244, 4021 "update_max_batches": 15164, 4022 "update_period": "25093s" 4023 }, 4024 "raft": { 4025 "election_timeout": "31947s", 4026 "heartbeat_timeout": "25699s", 4027 "leader_lease_timeout": "15351s" 4028 }, 4029 "server": { 4030 "health_interval": "17455s" 4031 } 4032 } 4033 }`, 4034 }, 4035 }, 4036 "hcl": []Source{ 4037 { 4038 Name: "tail.non-user.hcl", 4039 Format: "hcl", 4040 Data: ` 4041 acl_disabled_ttl = "957s" 4042 acl = { 4043 disabled_ttl = "957s" 4044 } 4045 ae_interval = "10003s" 4046 check_deregister_interval_min = "27870s" 4047 check_reap_interval = "10662s" 4048 discovery_max_stale = "5s" 4049 segment_limit = 24705 4050 segment_name_limit = 27046 4051 sync_coordinate_interval_min = "27983s" 4052 sync_coordinate_rate_target = 137.81 4053 `, 4054 }, 4055 { 4056 Name: "tail.consul.hcl", 4057 Format: "hcl", 4058 Data: ` 4059 consul = { 4060 coordinate = { 4061 update_batch_size = 9244 4062 update_max_batches = 15164 4063 update_period = "25093s" 4064 } 4065 raft = { 4066 election_timeout = "31947s" 4067 heartbeat_timeout = "25699s" 4068 leader_lease_timeout = "15351s" 4069 } 4070 server = { 4071 health_interval = "17455s" 4072 } 4073 } 4074 `, 4075 }, 4076 }, 4077 } 4078 4079 want := RuntimeConfig{ 4080 // non-user configurable values 4081 ACLDisabledTTL: 957 * time.Second, 4082 AEInterval: 10003 * time.Second, 4083 CheckDeregisterIntervalMin: 27870 * time.Second, 4084 CheckReapInterval: 10662 * time.Second, 4085 SegmentLimit: 24705, 4086 SegmentNameLimit: 27046, 4087 SyncCoordinateIntervalMin: 27983 * time.Second, 4088 SyncCoordinateRateTarget: 137.81, 4089 4090 Revision: "JNtPSav3", 4091 Version: "R909Hblt", 4092 VersionPrerelease: "ZT1JOQLn", 4093 4094 // consul configuration 4095 ConsulCoordinateUpdateBatchSize: 9244, 4096 ConsulCoordinateUpdateMaxBatches: 15164, 4097 ConsulCoordinateUpdatePeriod: 25093 * time.Second, 4098 ConsulRaftElectionTimeout: 5 * 31947 * time.Second, 4099 ConsulRaftHeartbeatTimeout: 5 * 25699 * time.Second, 4100 ConsulRaftLeaderLeaseTimeout: 5 * 15351 * time.Second, 4101 GossipLANGossipInterval: 25252 * time.Second, 4102 GossipLANGossipNodes: 6, 4103 GossipLANProbeInterval: 101 * time.Millisecond, 4104 GossipLANProbeTimeout: 102 * time.Millisecond, 4105 GossipLANSuspicionMult: 1235, 4106 GossipLANRetransmitMult: 1234, 4107 GossipWANGossipInterval: 6966 * time.Second, 4108 GossipWANGossipNodes: 2, 4109 GossipWANProbeInterval: 103 * time.Millisecond, 4110 GossipWANProbeTimeout: 104 * time.Millisecond, 4111 GossipWANSuspicionMult: 16385, 4112 GossipWANRetransmitMult: 16384, 4113 ConsulServerHealthInterval: 17455 * time.Second, 4114 4115 // user configurable values 4116 4117 ACLAgentMasterToken: "64fd0e08", 4118 ACLAgentToken: "bed2377c", 4119 ACLsEnabled: true, 4120 ACLDatacenter: "ejtmd43d", 4121 ACLDefaultPolicy: "72c2e7a0", 4122 ACLDownPolicy: "03eb2aee", 4123 ACLEnforceVersion8: true, 4124 ACLEnableKeyListPolicy: false, 4125 ACLEnableTokenPersistence: true, 4126 ACLMasterToken: "8a19ac27", 4127 ACLReplicationToken: "5795983a", 4128 ACLTokenTTL: 3321 * time.Second, 4129 ACLPolicyTTL: 1123 * time.Second, 4130 ACLToken: "418fdff1", 4131 ACLTokenReplication: true, 4132 AdvertiseAddrLAN: ipAddr("17.99.29.16"), 4133 AdvertiseAddrWAN: ipAddr("78.63.37.19"), 4134 AutopilotCleanupDeadServers: true, 4135 AutopilotDisableUpgradeMigration: true, 4136 AutopilotLastContactThreshold: 12705 * time.Second, 4137 AutopilotMaxTrailingLogs: 17849, 4138 AutopilotRedundancyZoneTag: "3IsufDJf", 4139 AutopilotServerStabilizationTime: 23057 * time.Second, 4140 AutopilotUpgradeVersionTag: "W9pDwFAL", 4141 BindAddr: ipAddr("16.99.34.17"), 4142 Bootstrap: true, 4143 BootstrapExpect: 53, 4144 CAFile: "erA7T0PM", 4145 CAPath: "mQEN1Mfp", 4146 CertFile: "7s4QAzDk", 4147 Checks: []*structs.CheckDefinition{ 4148 &structs.CheckDefinition{ 4149 ID: "uAjE6m9Z", 4150 Name: "QsZRGpYr", 4151 Notes: "VJ7Sk4BY", 4152 ServiceID: "lSulPcyz", 4153 Token: "toO59sh8", 4154 Status: "9RlWsXMV", 4155 ScriptArgs: []string{"4BAJttck", "4D2NPtTQ"}, 4156 HTTP: "dohLcyQ2", 4157 Header: map[string][]string{ 4158 "ZBfTin3L": []string{"1sDbEqYG", "lJGASsWK"}, 4159 "Ui0nU99X": []string{"LMccm3Qe", "k5H5RggQ"}, 4160 }, 4161 Method: "aldrIQ4l", 4162 TCP: "RJQND605", 4163 Interval: 22164 * time.Second, 4164 DockerContainerID: "ipgdFtjd", 4165 Shell: "qAeOYy0M", 4166 TLSSkipVerify: true, 4167 Timeout: 1813 * time.Second, 4168 TTL: 21743 * time.Second, 4169 DeregisterCriticalServiceAfter: 14232 * time.Second, 4170 }, 4171 &structs.CheckDefinition{ 4172 ID: "Cqq95BhP", 4173 Name: "3qXpkS0i", 4174 Notes: "sb5qLTex", 4175 ServiceID: "CmUUcRna", 4176 Token: "a3nQzHuy", 4177 Status: "irj26nf3", 4178 ScriptArgs: []string{"9s526ogY", "gSlOHj1w"}, 4179 HTTP: "yzhgsQ7Y", 4180 Header: map[string][]string{ 4181 "zcqwA8dO": []string{"qb1zx0DL", "sXCxPFsD"}, 4182 "qxvdnSE9": []string{"6wBPUYdF", "YYh8wtSZ"}, 4183 }, 4184 Method: "gLrztrNw", 4185 TCP: "4jG5casb", 4186 Interval: 28767 * time.Second, 4187 DockerContainerID: "THW6u7rL", 4188 Shell: "C1Zt3Zwh", 4189 TLSSkipVerify: true, 4190 Timeout: 18506 * time.Second, 4191 TTL: 31006 * time.Second, 4192 DeregisterCriticalServiceAfter: 2366 * time.Second, 4193 }, 4194 &structs.CheckDefinition{ 4195 ID: "fZaCAXww", 4196 Name: "OOM2eo0f", 4197 Notes: "zXzXI9Gt", 4198 ServiceID: "L8G0QNmR", 4199 Token: "oo4BCTgJ", 4200 Status: "qLykAl5u", 4201 ScriptArgs: []string{"f3BemRjy", "e5zgpef7"}, 4202 HTTP: "29B93haH", 4203 Header: map[string][]string{ 4204 "hBq0zn1q": {"2a9o9ZKP", "vKwA5lR6"}, 4205 "f3r6xFtM": {"RyuIdDWv", "QbxEcIUM"}, 4206 }, 4207 Method: "Dou0nGT5", 4208 TCP: "JY6fTTcw", 4209 Interval: 18714 * time.Second, 4210 DockerContainerID: "qF66POS9", 4211 Shell: "sOnDy228", 4212 TLSSkipVerify: true, 4213 Timeout: 5954 * time.Second, 4214 TTL: 30044 * time.Second, 4215 DeregisterCriticalServiceAfter: 13209 * time.Second, 4216 }, 4217 }, 4218 CheckUpdateInterval: 16507 * time.Second, 4219 ClientAddrs: []*net.IPAddr{ipAddr("93.83.18.19")}, 4220 ConnectEnabled: true, 4221 ConnectProxyBindMinPort: 2000, 4222 ConnectProxyBindMaxPort: 3000, 4223 ConnectSidecarMinPort: 8888, 4224 ConnectSidecarMaxPort: 9999, 4225 ConnectCAProvider: "consul", 4226 ConnectCAConfig: map[string]interface{}{ 4227 "RotationPeriod": "90h", 4228 "LeafCertTTL": "1h", 4229 "CSRMaxPerSecond": float64(100), 4230 "CSRMaxConcurrent": float64(2), 4231 }, 4232 ConnectProxyAllowManagedRoot: false, 4233 ConnectProxyAllowManagedAPIRegistration: false, 4234 ConnectProxyDefaultExecMode: "script", 4235 ConnectProxyDefaultDaemonCommand: []string{"consul", "connect", "proxy"}, 4236 ConnectProxyDefaultScriptCommand: []string{"proxyctl.sh"}, 4237 ConnectProxyDefaultConfig: map[string]interface{}{ 4238 "foo": "bar", 4239 "connect_timeout_ms": float64(1000), 4240 "pedantic_mode": true, 4241 }, 4242 DNSAddrs: []net.Addr{tcpAddr("93.95.95.81:7001"), udpAddr("93.95.95.81:7001")}, 4243 DNSARecordLimit: 29907, 4244 DNSAllowStale: true, 4245 DNSDisableCompression: true, 4246 DNSDomain: "7W1xXSqd", 4247 DNSEnableTruncate: true, 4248 DNSMaxStale: 29685 * time.Second, 4249 DNSNodeTTL: 7084 * time.Second, 4250 DNSOnlyPassing: true, 4251 DNSPort: 7001, 4252 DNSRecursorTimeout: 4427 * time.Second, 4253 DNSRecursors: []string{"63.38.39.58", "92.49.18.18"}, 4254 DNSSOA: RuntimeSOAConfig{Refresh: 3600, Retry: 600, Expire: 86400, Minttl: 0}, 4255 DNSServiceTTL: map[string]time.Duration{"*": 32030 * time.Second}, 4256 DNSUDPAnswerLimit: 29909, 4257 DNSNodeMetaTXT: true, 4258 DNSUseCache: true, 4259 DNSCacheMaxAge: 5 * time.Minute, 4260 DataDir: dataDir, 4261 Datacenter: "rzo029wg", 4262 DevMode: true, 4263 DisableAnonymousSignature: true, 4264 DisableCoordinates: true, 4265 DisableHostNodeID: true, 4266 DisableHTTPUnprintableCharFilter: true, 4267 DisableKeyringFile: true, 4268 DisableRemoteExec: true, 4269 DisableUpdateCheck: true, 4270 DiscardCheckOutput: true, 4271 DiscoveryMaxStale: 5 * time.Second, 4272 EnableAgentTLSForChecks: true, 4273 EnableDebug: true, 4274 EnableRemoteScriptChecks: true, 4275 EnableLocalScriptChecks: true, 4276 EnableSyslog: true, 4277 EnableUI: true, 4278 EncryptKey: "A4wELWqH", 4279 EncryptVerifyIncoming: true, 4280 EncryptVerifyOutgoing: true, 4281 GRPCPort: 4881, 4282 GRPCAddrs: []net.Addr{tcpAddr("32.31.61.91:4881")}, 4283 HTTPAddrs: []net.Addr{tcpAddr("83.39.91.39:7999")}, 4284 HTTPBlockEndpoints: []string{"RBvAFcGD", "fWOWFznh"}, 4285 AllowWriteHTTPFrom: []*net.IPNet{cidr("127.0.0.0/8"), cidr("22.33.44.55/32"), cidr("0.0.0.0/0")}, 4286 HTTPPort: 7999, 4287 HTTPResponseHeaders: map[string]string{"M6TKa9NP": "xjuxjOzQ", "JRCrHZed": "rl0mTx81"}, 4288 HTTPSAddrs: []net.Addr{tcpAddr("95.17.17.19:15127")}, 4289 HTTPSPort: 15127, 4290 KeyFile: "IEkkwgIA", 4291 LeaveDrainTime: 8265 * time.Second, 4292 LeaveOnTerm: true, 4293 LogLevel: "k1zo9Spt", 4294 NodeID: types.NodeID("AsUIlw99"), 4295 NodeMeta: map[string]string{"5mgGQMBk": "mJLtVMSG", "A7ynFMJB": "0Nx6RGab"}, 4296 NodeName: "otlLxGaI", 4297 NonVotingServer: true, 4298 PidFile: "43xN80Km", 4299 PrimaryDatacenter: "ejtmd43d", 4300 RPCAdvertiseAddr: tcpAddr("17.99.29.16:3757"), 4301 RPCBindAddr: tcpAddr("16.99.34.17:3757"), 4302 RPCHoldTimeout: 15707 * time.Second, 4303 RPCProtocol: 30793, 4304 RPCRateLimit: 12029.43, 4305 RPCMaxBurst: 44848, 4306 RaftProtocol: 19016, 4307 RaftSnapshotThreshold: 16384, 4308 RaftSnapshotInterval: 30 * time.Second, 4309 ReconnectTimeoutLAN: 23739 * time.Second, 4310 ReconnectTimeoutWAN: 26694 * time.Second, 4311 RejoinAfterLeave: true, 4312 RetryJoinIntervalLAN: 8067 * time.Second, 4313 RetryJoinIntervalWAN: 28866 * time.Second, 4314 RetryJoinLAN: []string{"pbsSFY7U", "l0qLtWij"}, 4315 RetryJoinMaxAttemptsLAN: 913, 4316 RetryJoinMaxAttemptsWAN: 23160, 4317 RetryJoinWAN: []string{"PFsR02Ye", "rJdQIhER"}, 4318 SegmentName: "BC2NhTDi", 4319 Segments: []structs.NetworkSegment{ 4320 { 4321 Name: "PExYMe2E", 4322 Bind: tcpAddr("36.73.36.19:38295"), 4323 Advertise: tcpAddr("63.39.19.18:38295"), 4324 RPCListener: true, 4325 }, 4326 { 4327 Name: "UzCvJgup", 4328 Bind: tcpAddr("37.58.38.19:39292"), 4329 Advertise: tcpAddr("83.58.26.27:39292"), 4330 RPCListener: true, 4331 }, 4332 }, 4333 SerfPortLAN: 8301, 4334 SerfPortWAN: 8302, 4335 ServerMode: true, 4336 ServerName: "Oerr9n1G", 4337 ServerPort: 3757, 4338 Services: []*structs.ServiceDefinition{ 4339 { 4340 ID: "wI1dzxS4", 4341 Name: "7IszXMQ1", 4342 Tags: []string{"0Zwg8l6v", "zebELdN5"}, 4343 Address: "9RhqPSPB", 4344 Token: "myjKJkWH", 4345 Port: 72219, 4346 Weights: &structs.Weights{ 4347 Passing: 1, 4348 Warning: 1, 4349 }, 4350 EnableTagOverride: true, 4351 Checks: []*structs.CheckType{ 4352 &structs.CheckType{ 4353 CheckID: "qmfeO5if", 4354 Name: "atDGP7n5", 4355 Status: "pDQKEhWL", 4356 Notes: "Yt8EDLev", 4357 ScriptArgs: []string{"81EDZLPa", "bPY5X8xd"}, 4358 HTTP: "qzHYvmJO", 4359 Header: map[string][]string{ 4360 "UkpmZ3a3": {"2dfzXuxZ"}, 4361 "cVFpko4u": {"gGqdEB6k", "9LsRo22u"}, 4362 }, 4363 Method: "X5DrovFc", 4364 TCP: "ICbxkpSF", 4365 Interval: 24392 * time.Second, 4366 DockerContainerID: "ZKXr68Yb", 4367 Shell: "CEfzx0Fo", 4368 TLSSkipVerify: true, 4369 Timeout: 38333 * time.Second, 4370 TTL: 57201 * time.Second, 4371 DeregisterCriticalServiceAfter: 44214 * time.Second, 4372 }, 4373 }, 4374 // Note that although this SidecarService is only syntax sugar for 4375 // registering another service, that has to happen in the agent code so 4376 // it can make intelligent decisions about automatic port assignments 4377 // etc. So we expect config just to pass it through verbatim. 4378 Connect: &structs.ServiceConnect{ 4379 SidecarService: &structs.ServiceDefinition{ 4380 Weights: &structs.Weights{ 4381 Passing: 1, 4382 Warning: 1, 4383 }, 4384 }, 4385 }, 4386 }, 4387 { 4388 ID: "MRHVMZuD", 4389 Name: "6L6BVfgH", 4390 Tags: []string{"7Ale4y6o", "PMBW08hy"}, 4391 Address: "R6H6g8h0", 4392 Token: "ZgY8gjMI", 4393 Port: 38292, 4394 Weights: &structs.Weights{ 4395 Passing: 1979, 4396 Warning: 6, 4397 }, 4398 EnableTagOverride: true, 4399 Checks: structs.CheckTypes{ 4400 &structs.CheckType{ 4401 CheckID: "GTti9hCo", 4402 Name: "9OOS93ne", 4403 Notes: "CQy86DH0", 4404 Status: "P0SWDvrk", 4405 ScriptArgs: []string{"EXvkYIuG", "BATOyt6h"}, 4406 HTTP: "u97ByEiW", 4407 Header: map[string][]string{ 4408 "MUlReo8L": {"AUZG7wHG", "gsN0Dc2N"}, 4409 "1UJXjVrT": {"OJgxzTfk", "xZZrFsq7"}, 4410 }, 4411 Method: "5wkAxCUE", 4412 TCP: "MN3oA9D2", 4413 Interval: 32718 * time.Second, 4414 DockerContainerID: "cU15LMet", 4415 Shell: "nEz9qz2l", 4416 TLSSkipVerify: true, 4417 Timeout: 34738 * time.Second, 4418 TTL: 22773 * time.Second, 4419 DeregisterCriticalServiceAfter: 84282 * time.Second, 4420 }, 4421 &structs.CheckType{ 4422 CheckID: "UHsDeLxG", 4423 Name: "PQSaPWlT", 4424 Notes: "jKChDOdl", 4425 Status: "5qFz6OZn", 4426 ScriptArgs: []string{"NMtYWlT9", "vj74JXsm"}, 4427 HTTP: "1LBDJhw4", 4428 Header: map[string][]string{ 4429 "cXPmnv1M": {"imDqfaBx", "NFxZ1bQe"}, 4430 "vr7wY7CS": {"EtCoNPPL", "9vAarJ5s"}, 4431 }, 4432 Method: "wzByP903", 4433 TCP: "2exjZIGE", 4434 Interval: 5656 * time.Second, 4435 DockerContainerID: "5tDBWpfA", 4436 Shell: "rlTpLM8s", 4437 TLSSkipVerify: true, 4438 Timeout: 4868 * time.Second, 4439 TTL: 11222 * time.Second, 4440 DeregisterCriticalServiceAfter: 68482 * time.Second, 4441 }, 4442 }, 4443 Connect: &structs.ServiceConnect{ 4444 Proxy: &structs.ServiceDefinitionConnectProxy{ 4445 ExecMode: "daemon", 4446 Command: []string{"awesome-proxy"}, 4447 Config: map[string]interface{}{ 4448 "foo": "qux", 4449 }, 4450 }, 4451 }, 4452 }, 4453 { 4454 ID: "Kh81CPF6", 4455 Name: "Kh81CPF6-proxy", 4456 Port: 31471, 4457 Kind: "connect-proxy", 4458 Proxy: &structs.ConnectProxyConfig{ 4459 DestinationServiceName: "6L6BVfgH", 4460 DestinationServiceID: "6L6BVfgH-id", 4461 LocalServiceAddress: "127.0.0.2", 4462 LocalServicePort: 23759, 4463 Config: map[string]interface{}{ 4464 "cedGGtZf": "pWrUNiWw", 4465 }, 4466 Upstreams: structs.Upstreams{ 4467 { 4468 DestinationType: "service", // Default should be explicitly filled 4469 DestinationName: "KPtAj2cb", 4470 LocalBindPort: 4051, 4471 Config: map[string]interface{}{ 4472 "kzRnZOyd": "nUNKoL8H", 4473 }, 4474 }, 4475 { 4476 DestinationType: "prepared_query", 4477 DestinationNamespace: "9nakw0td", 4478 DestinationName: "KSd8HsRl", 4479 LocalBindPort: 11884, 4480 LocalBindAddress: "127.24.88.0", 4481 }, 4482 }, 4483 }, 4484 Weights: &structs.Weights{ 4485 Passing: 1, 4486 Warning: 1, 4487 }, 4488 }, 4489 { 4490 ID: "dLOXpSCI", 4491 Name: "o1ynPkp0", 4492 Tags: []string{"nkwshvM5", "NTDWn3ek"}, 4493 Address: "cOlSOhbp", 4494 Token: "msy7iWER", 4495 Meta: map[string]string{"mymeta": "data"}, 4496 Port: 24237, 4497 Weights: &structs.Weights{ 4498 Passing: 100, 4499 Warning: 1, 4500 }, 4501 EnableTagOverride: true, 4502 Connect: &structs.ServiceConnect{ 4503 Native: true, 4504 }, 4505 Checks: structs.CheckTypes{ 4506 &structs.CheckType{ 4507 CheckID: "Zv99e9Ka", 4508 Name: "sgV4F7Pk", 4509 Notes: "yP5nKbW0", 4510 Status: "7oLMEyfu", 4511 ScriptArgs: []string{"5wEZtZpv", "0Ihyk8cS"}, 4512 HTTP: "KyDjGY9H", 4513 Header: map[string][]string{ 4514 "gv5qefTz": {"5Olo2pMG", "PvvKWQU5"}, 4515 "SHOVq1Vv": {"jntFhyym", "GYJh32pp"}, 4516 }, 4517 Method: "T66MFBfR", 4518 TCP: "bNnNfx2A", 4519 Interval: 22224 * time.Second, 4520 DockerContainerID: "ipgdFtjd", 4521 Shell: "omVZq7Sz", 4522 TLSSkipVerify: true, 4523 Timeout: 18913 * time.Second, 4524 TTL: 44743 * time.Second, 4525 DeregisterCriticalServiceAfter: 8482 * time.Second, 4526 }, 4527 &structs.CheckType{ 4528 CheckID: "G79O6Mpr", 4529 Name: "IEqrzrsd", 4530 Notes: "SVqApqeM", 4531 Status: "XXkVoZXt", 4532 ScriptArgs: []string{"wD05Bvao", "rLYB7kQC"}, 4533 HTTP: "kyICZsn8", 4534 Header: map[string][]string{ 4535 "4ebP5vL4": {"G20SrL5Q", "DwPKlMbo"}, 4536 "p2UI34Qz": {"UsG1D0Qh", "NHhRiB6s"}, 4537 }, 4538 Method: "ciYHWors", 4539 TCP: "FfvCwlqH", 4540 Interval: 12356 * time.Second, 4541 DockerContainerID: "HBndBU6R", 4542 Shell: "hVI33JjA", 4543 TLSSkipVerify: true, 4544 Timeout: 38282 * time.Second, 4545 TTL: 1181 * time.Second, 4546 DeregisterCriticalServiceAfter: 4992 * time.Second, 4547 }, 4548 &structs.CheckType{ 4549 CheckID: "RMi85Dv8", 4550 Name: "iehanzuq", 4551 Status: "rCvn53TH", 4552 Notes: "fti5lfF3", 4553 ScriptArgs: []string{"16WRUmwS", "QWk7j7ae"}, 4554 HTTP: "dl3Fgme3", 4555 Header: map[string][]string{ 4556 "rjm4DEd3": {"2m3m2Fls"}, 4557 "l4HwQ112": {"fk56MNlo", "dhLK56aZ"}, 4558 }, 4559 Method: "9afLm3Mj", 4560 TCP: "fjiLFqVd", 4561 Interval: 23926 * time.Second, 4562 DockerContainerID: "dO5TtRHk", 4563 Shell: "e6q2ttES", 4564 TLSSkipVerify: true, 4565 Timeout: 38483 * time.Second, 4566 TTL: 10943 * time.Second, 4567 DeregisterCriticalServiceAfter: 68787 * time.Second, 4568 }, 4569 }, 4570 }, 4571 }, 4572 SerfAdvertiseAddrLAN: tcpAddr("17.99.29.16:8301"), 4573 SerfAdvertiseAddrWAN: tcpAddr("78.63.37.19:8302"), 4574 SerfBindAddrLAN: tcpAddr("99.43.63.15:8301"), 4575 SerfBindAddrWAN: tcpAddr("67.88.33.19:8302"), 4576 SessionTTLMin: 26627 * time.Second, 4577 SkipLeaveOnInt: true, 4578 StartJoinAddrsLAN: []string{"LR3hGDoG", "MwVpZ4Up"}, 4579 StartJoinAddrsWAN: []string{"EbFSc3nA", "kwXTh623"}, 4580 SyslogFacility: "hHv79Uia", 4581 Telemetry: lib.TelemetryConfig{ 4582 CirconusAPIApp: "p4QOTe9j", 4583 CirconusAPIToken: "E3j35V23", 4584 CirconusAPIURL: "mEMjHpGg", 4585 CirconusBrokerID: "BHlxUhed", 4586 CirconusBrokerSelectTag: "13xy1gHm", 4587 CirconusCheckDisplayName: "DRSlQR6n", 4588 CirconusCheckForceMetricActivation: "Ua5FGVYf", 4589 CirconusCheckID: "kGorutad", 4590 CirconusCheckInstanceID: "rwoOL6R4", 4591 CirconusCheckSearchTag: "ovT4hT4f", 4592 CirconusCheckTags: "prvO4uBl", 4593 CirconusSubmissionInterval: "DolzaflP", 4594 CirconusSubmissionURL: "gTcbS93G", 4595 DisableHostname: true, 4596 DogstatsdAddr: "0wSndumK", 4597 DogstatsdTags: []string{"3N81zSUB", "Xtj8AnXZ"}, 4598 FilterDefault: true, 4599 AllowedPrefixes: []string{"oJotS8XJ"}, 4600 BlockedPrefixes: []string{"cazlEhGn"}, 4601 MetricsPrefix: "ftO6DySn", 4602 PrometheusRetentionTime: 15 * time.Second, 4603 StatsdAddr: "drce87cy", 4604 StatsiteAddr: "HpFwKB8R", 4605 }, 4606 TLSCipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384}, 4607 TLSMinVersion: "pAOWafkR", 4608 TLSPreferServerCipherSuites: true, 4609 TaggedAddresses: map[string]string{ 4610 "7MYgHrYH": "dALJAhLD", 4611 "h6DdBy6K": "ebrr9zZ8", 4612 "lan": "17.99.29.16", 4613 "wan": "78.63.37.19", 4614 }, 4615 TranslateWANAddrs: true, 4616 UIDir: "11IFzAUn", 4617 UnixSocketUser: "E0nB1DwA", 4618 UnixSocketGroup: "8pFodrV8", 4619 UnixSocketMode: "E8sAwOv4", 4620 VerifyIncoming: true, 4621 VerifyIncomingHTTPS: true, 4622 VerifyIncomingRPC: true, 4623 VerifyOutgoing: true, 4624 VerifyServerHostname: true, 4625 Watches: []map[string]interface{}{ 4626 map[string]interface{}{ 4627 "type": "key", 4628 "datacenter": "GyE6jpeW", 4629 "key": "j9lF1Tve", 4630 "handler": "90N7S4LN", 4631 }, 4632 map[string]interface{}{ 4633 "type": "keyprefix", 4634 "datacenter": "fYrl3F5d", 4635 "key": "sl3Dffu7", 4636 "args": []interface{}{"dltjDJ2a", "flEa7C2d"}, 4637 }, 4638 }, 4639 } 4640 4641 warns := []string{ 4642 `The 'acl_datacenter' field is deprecated. Use the 'primary_datacenter' field instead.`, 4643 `bootstrap_expect > 0: expecting 53 servers`, 4644 } 4645 4646 // ensure that all fields are set to unique non-zero values 4647 // todo(fs): This currently fails since ServiceDefinition.Check is not used 4648 // todo(fs): not sure on how to work around this. Possible options are: 4649 // todo(fs): * move first check into the Check field 4650 // todo(fs): * ignore the Check field 4651 // todo(fs): both feel like a hack 4652 if err := nonZero("RuntimeConfig", nil, want); err != nil { 4653 t.Log(err) 4654 } 4655 4656 for format, data := range src { 4657 t.Run(format, func(t *testing.T) { 4658 // parse the flags since this is the only way we can set the 4659 // DevMode flag 4660 var flags Flags 4661 fs := flag.NewFlagSet("", flag.ContinueOnError) 4662 AddFlags(fs, &flags) 4663 if err := fs.Parse(flagSrc); err != nil { 4664 t.Fatalf("ParseFlags: %s", err) 4665 } 4666 4667 // ensure that all fields are set to unique non-zero values 4668 // if err := nonZero("Config", nil, c); err != nil { 4669 // t.Fatal(err) 4670 // } 4671 4672 b, err := NewBuilder(flags) 4673 if err != nil { 4674 t.Fatalf("NewBuilder: %s", err) 4675 } 4676 b.Sources = append(b.Sources, Source{Name: "full." + format, Data: data}) 4677 b.Tail = append(b.Tail, tail[format]...) 4678 b.Tail = append(b.Tail, VersionSource("JNtPSav3", "R909Hblt", "ZT1JOQLn")) 4679 4680 // construct the runtime config 4681 rt, err := b.Build() 4682 if err != nil { 4683 t.Fatalf("Build: %s", err) 4684 } 4685 4686 // verify that all fields are set 4687 if !verify.Values(t, "runtime_config", rt, want) { 4688 t.FailNow() 4689 } 4690 4691 // at this point we have confirmed that the parsing worked 4692 // for all fields but the validation will fail since certain 4693 // combinations are not allowed. Since it is not possible to have 4694 // all fields with non-zero values and to have a valid configuration 4695 // we are patching a handful of safe fields to make validation pass. 4696 rt.Bootstrap = false 4697 rt.DevMode = false 4698 rt.EnableUI = false 4699 rt.SegmentName = "" 4700 rt.Segments = nil 4701 4702 // validate the runtime config 4703 if err := b.Validate(rt); err != nil { 4704 t.Fatalf("Validate: %s", err) 4705 } 4706 4707 // check the warnings 4708 if got, want := b.Warnings, warns; !verify.Values(t, "warnings", got, want) { 4709 t.FailNow() 4710 } 4711 }) 4712 } 4713 } 4714 4715 // nonZero verifies recursively that all fields are set to unique, 4716 // non-zero and non-nil values. 4717 // 4718 // struct: check all fields recursively 4719 // slice: check len > 0 and all values recursively 4720 // ptr: check not nil 4721 // bool: check not zero (cannot check uniqueness) 4722 // string, int, uint: check not zero and unique 4723 // other: error 4724 func nonZero(name string, uniq map[interface{}]string, v interface{}) error { 4725 if v == nil { 4726 return fmt.Errorf("%q is nil", name) 4727 } 4728 4729 if uniq == nil { 4730 uniq = map[interface{}]string{} 4731 } 4732 4733 isUnique := func(v interface{}) error { 4734 if other := uniq[v]; other != "" { 4735 return fmt.Errorf("%q and %q both use value %q", name, other, v) 4736 } 4737 uniq[v] = name 4738 return nil 4739 } 4740 4741 val, typ := reflect.ValueOf(v), reflect.TypeOf(v) 4742 // fmt.Printf("%s: %T\n", name, v) 4743 switch typ.Kind() { 4744 case reflect.Struct: 4745 for i := 0; i < typ.NumField(); i++ { 4746 f := typ.Field(i) 4747 fieldname := fmt.Sprintf("%s.%s", name, f.Name) 4748 err := nonZero(fieldname, uniq, val.Field(i).Interface()) 4749 if err != nil { 4750 return err 4751 } 4752 } 4753 4754 case reflect.Slice: 4755 if val.Len() == 0 { 4756 return fmt.Errorf("%q is empty slice", name) 4757 } 4758 for i := 0; i < val.Len(); i++ { 4759 elemname := fmt.Sprintf("%s[%d]", name, i) 4760 err := nonZero(elemname, uniq, val.Index(i).Interface()) 4761 if err != nil { 4762 return err 4763 } 4764 } 4765 4766 case reflect.Map: 4767 if val.Len() == 0 { 4768 return fmt.Errorf("%q is empty map", name) 4769 } 4770 for _, key := range val.MapKeys() { 4771 keyname := fmt.Sprintf("%s[%s]", name, key.String()) 4772 if err := nonZero(keyname, uniq, key.Interface()); err != nil { 4773 if strings.Contains(err.Error(), "is zero value") { 4774 return fmt.Errorf("%q has zero value map key", name) 4775 } 4776 return err 4777 } 4778 if err := nonZero(keyname, uniq, val.MapIndex(key).Interface()); err != nil { 4779 return err 4780 } 4781 } 4782 4783 case reflect.Bool: 4784 if val.Bool() != true { 4785 return fmt.Errorf("%q is zero value", name) 4786 } 4787 // do not test bool for uniqueness since there are only two values 4788 4789 case reflect.String: 4790 if val.Len() == 0 { 4791 return fmt.Errorf("%q is zero value", name) 4792 } 4793 return isUnique(v) 4794 4795 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 4796 if val.Int() == 0 { 4797 return fmt.Errorf("%q is zero value", name) 4798 } 4799 return isUnique(v) 4800 4801 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 4802 if val.Uint() == 0 { 4803 return fmt.Errorf("%q is zero value", name) 4804 } 4805 return isUnique(v) 4806 4807 case reflect.Float32, reflect.Float64: 4808 if val.Float() == 0 { 4809 return fmt.Errorf("%q is zero value", name) 4810 } 4811 return isUnique(v) 4812 4813 case reflect.Ptr: 4814 if val.IsNil() { 4815 return fmt.Errorf("%q is nil", name) 4816 } 4817 return nonZero("*"+name, uniq, val.Elem().Interface()) 4818 4819 default: 4820 return fmt.Errorf("%T is not supported", v) 4821 } 4822 return nil 4823 } 4824 4825 func TestNonZero(t *testing.T) { 4826 var empty string 4827 4828 tests := []struct { 4829 desc string 4830 v interface{} 4831 err error 4832 }{ 4833 {"nil", nil, errors.New(`"x" is nil`)}, 4834 {"zero bool", false, errors.New(`"x" is zero value`)}, 4835 {"zero string", "", errors.New(`"x" is zero value`)}, 4836 {"zero int", int(0), errors.New(`"x" is zero value`)}, 4837 {"zero int8", int8(0), errors.New(`"x" is zero value`)}, 4838 {"zero int16", int16(0), errors.New(`"x" is zero value`)}, 4839 {"zero int32", int32(0), errors.New(`"x" is zero value`)}, 4840 {"zero int64", int64(0), errors.New(`"x" is zero value`)}, 4841 {"zero uint", uint(0), errors.New(`"x" is zero value`)}, 4842 {"zero uint8", uint8(0), errors.New(`"x" is zero value`)}, 4843 {"zero uint16", uint16(0), errors.New(`"x" is zero value`)}, 4844 {"zero uint32", uint32(0), errors.New(`"x" is zero value`)}, 4845 {"zero uint64", uint64(0), errors.New(`"x" is zero value`)}, 4846 {"zero float32", float32(0), errors.New(`"x" is zero value`)}, 4847 {"zero float64", float64(0), errors.New(`"x" is zero value`)}, 4848 {"ptr to zero value", &empty, errors.New(`"*x" is zero value`)}, 4849 {"empty slice", []string{}, errors.New(`"x" is empty slice`)}, 4850 {"slice with zero value", []string{""}, errors.New(`"x[0]" is zero value`)}, 4851 {"empty map", map[string]string{}, errors.New(`"x" is empty map`)}, 4852 {"map with zero value key", map[string]string{"": "y"}, errors.New(`"x" has zero value map key`)}, 4853 {"map with zero value elem", map[string]string{"y": ""}, errors.New(`"x[y]" is zero value`)}, 4854 {"struct with nil field", struct{ Y *int }{}, errors.New(`"x.Y" is nil`)}, 4855 {"struct with zero value field", struct{ Y string }{}, errors.New(`"x.Y" is zero value`)}, 4856 {"struct with empty array", struct{ Y []string }{}, errors.New(`"x.Y" is empty slice`)}, 4857 } 4858 4859 for _, tt := range tests { 4860 t.Run(tt.desc, func(t *testing.T) { 4861 if got, want := nonZero("x", nil, tt.v), tt.err; !reflect.DeepEqual(got, want) { 4862 t.Fatalf("got error %v want %v", got, want) 4863 } 4864 }) 4865 } 4866 } 4867 4868 func TestConfigDecodeBytes(t *testing.T) { 4869 t.Parallel() 4870 // Test with some input 4871 src := []byte("abc") 4872 key := base64.StdEncoding.EncodeToString(src) 4873 4874 result, err := decodeBytes(key) 4875 if err != nil { 4876 t.Fatalf("err: %s", err) 4877 } 4878 4879 if !bytes.Equal(src, result) { 4880 t.Fatalf("bad: %#v", result) 4881 } 4882 4883 // Test with no input 4884 result, err = decodeBytes("") 4885 if err != nil { 4886 t.Fatalf("err: %s", err) 4887 } 4888 4889 if len(result) > 0 { 4890 t.Fatalf("bad: %#v", result) 4891 } 4892 } 4893 4894 func TestSanitize(t *testing.T) { 4895 rt := RuntimeConfig{ 4896 BindAddr: &net.IPAddr{IP: net.ParseIP("127.0.0.1")}, 4897 SerfAdvertiseAddrLAN: &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678}, 4898 DNSAddrs: []net.Addr{ 4899 &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678}, 4900 &net.UDPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678}, 4901 }, 4902 DNSSOA: RuntimeSOAConfig{Refresh: 3600, Retry: 600, Expire: 86400, Minttl: 0}, 4903 HTTPAddrs: []net.Addr{ 4904 &net.TCPAddr{IP: net.ParseIP("1.2.3.4"), Port: 5678}, 4905 &net.UnixAddr{Name: "/var/run/foo"}, 4906 }, 4907 ConsulCoordinateUpdatePeriod: 15 * time.Second, 4908 RetryJoinLAN: []string{ 4909 "foo=bar key=baz secret=boom bang=bar", 4910 }, 4911 RetryJoinWAN: []string{ 4912 "wan_foo=bar wan_key=baz wan_secret=boom wan_bang=bar", 4913 }, 4914 Services: []*structs.ServiceDefinition{ 4915 &structs.ServiceDefinition{ 4916 Name: "foo", 4917 Token: "bar", 4918 Check: structs.CheckType{ 4919 Name: "blurb", 4920 }, 4921 Weights: &structs.Weights{ 4922 Passing: 67, 4923 Warning: 3, 4924 }, 4925 }, 4926 }, 4927 Checks: []*structs.CheckDefinition{ 4928 &structs.CheckDefinition{ 4929 Name: "zoo", 4930 Token: "zope", 4931 }, 4932 }, 4933 } 4934 4935 rtJSON := `{ 4936 "ACLAgentMasterToken": "hidden", 4937 "ACLAgentToken": "hidden", 4938 "ACLDatacenter": "", 4939 "ACLDefaultPolicy": "", 4940 "ACLDisabledTTL": "0s", 4941 "ACLDownPolicy": "", 4942 "ACLEnableKeyListPolicy": false, 4943 "ACLEnableTokenPersistence": false, 4944 "ACLEnforceVersion8": false, 4945 "ACLMasterToken": "hidden", 4946 "ACLPolicyTTL": "0s", 4947 "ACLReplicationToken": "hidden", 4948 "ACLTokenReplication": false, 4949 "ACLTokenTTL": "0s", 4950 "ACLToken": "hidden", 4951 "ACLsEnabled": false, 4952 "AEInterval": "0s", 4953 "AdvertiseAddrLAN": "", 4954 "AdvertiseAddrWAN": "", 4955 "AutopilotCleanupDeadServers": false, 4956 "AutopilotDisableUpgradeMigration": false, 4957 "AutopilotLastContactThreshold": "0s", 4958 "AutopilotMaxTrailingLogs": 0, 4959 "AutopilotRedundancyZoneTag": "", 4960 "AutopilotServerStabilizationTime": "0s", 4961 "AutopilotUpgradeVersionTag": "", 4962 "BindAddr": "127.0.0.1", 4963 "Bootstrap": false, 4964 "BootstrapExpect": 0, 4965 "CAFile": "", 4966 "CAPath": "", 4967 "CertFile": "", 4968 "CheckDeregisterIntervalMin": "0s", 4969 "CheckReapInterval": "0s", 4970 "CheckUpdateInterval": "0s", 4971 "Checks": [{ 4972 "AliasNode": "", 4973 "AliasService": "", 4974 "DeregisterCriticalServiceAfter": "0s", 4975 "DockerContainerID": "", 4976 "GRPC": "", 4977 "GRPCUseTLS": false, 4978 "HTTP": "", 4979 "Header": {}, 4980 "ID": "", 4981 "Interval": "0s", 4982 "Method": "", 4983 "Name": "zoo", 4984 "Notes": "", 4985 "ScriptArgs": [], 4986 "ServiceID": "", 4987 "Shell": "", 4988 "Status": "", 4989 "TCP": "", 4990 "TLSSkipVerify": false, 4991 "TTL": "0s", 4992 "Timeout": "0s", 4993 "Token": "hidden" 4994 }], 4995 "ClientAddrs": [], 4996 "ConnectCAConfig": {}, 4997 "ConnectCAProvider": "", 4998 "ConnectEnabled": false, 4999 "ConnectProxyAllowManagedAPIRegistration": false, 5000 "ConnectProxyAllowManagedRoot": false, 5001 "ConnectProxyBindMaxPort": 0, 5002 "ConnectProxyBindMinPort": 0, 5003 "ConnectProxyDefaultConfig": {}, 5004 "ConnectProxyDefaultDaemonCommand": [], 5005 "ConnectProxyDefaultExecMode": "", 5006 "ConnectProxyDefaultScriptCommand": [], 5007 "ConnectSidecarMaxPort": 0, 5008 "ConnectSidecarMinPort": 0, 5009 "ConnectTestCALeafRootChangeSpread": "0s", 5010 "ConnectTestDisableManagedProxies": false, 5011 "ConsulCoordinateUpdateBatchSize": 0, 5012 "ConsulCoordinateUpdateMaxBatches": 0, 5013 "ConsulCoordinateUpdatePeriod": "15s", 5014 "ConsulRaftElectionTimeout": "0s", 5015 "ConsulRaftHeartbeatTimeout": "0s", 5016 "ConsulRaftLeaderLeaseTimeout": "0s", 5017 "GossipLANGossipInterval": "0s", 5018 "GossipLANGossipNodes": 0, 5019 "GossipLANProbeInterval": "0s", 5020 "GossipLANProbeTimeout": "0s", 5021 "GossipLANRetransmitMult": 0, 5022 "GossipLANSuspicionMult": 0, 5023 "GossipWANGossipInterval": "0s", 5024 "GossipWANGossipNodes": 0, 5025 "GossipWANProbeInterval": "0s", 5026 "GossipWANProbeTimeout": "0s", 5027 "GossipWANRetransmitMult": 0, 5028 "GossipWANSuspicionMult": 0, 5029 "ConsulServerHealthInterval": "0s", 5030 "DNSARecordLimit": 0, 5031 "DNSAddrs": [ 5032 "tcp://1.2.3.4:5678", 5033 "udp://1.2.3.4:5678" 5034 ], 5035 "DNSAllowStale": false, 5036 "DNSDisableCompression": false, 5037 "DNSDomain": "", 5038 "DNSEnableTruncate": false, 5039 "DNSMaxStale": "0s", 5040 "DNSNodeMetaTXT": false, 5041 "DNSNodeTTL": "0s", 5042 "DNSOnlyPassing": false, 5043 "DNSPort": 0, 5044 "DNSRecursorTimeout": "0s", 5045 "DNSRecursors": [], 5046 "DNSServiceTTL": {}, 5047 "DNSSOA": { 5048 "Refresh": 3600, 5049 "Retry": 600, 5050 "Expire": 86400, 5051 "Minttl": 0 5052 }, 5053 "DNSUDPAnswerLimit": 0, 5054 "DNSUseCache": false, 5055 "DNSCacheMaxAge": "0s", 5056 "DataDir": "", 5057 "Datacenter": "", 5058 "DevMode": false, 5059 "DisableAnonymousSignature": false, 5060 "DisableCoordinates": false, 5061 "DisableHTTPUnprintableCharFilter": false, 5062 "DisableHostNodeID": false, 5063 "DisableKeyringFile": false, 5064 "DisableRemoteExec": false, 5065 "DisableUpdateCheck": false, 5066 "DiscardCheckOutput": false, 5067 "DiscoveryMaxStale": "0s", 5068 "EnableAgentTLSForChecks": false, 5069 "EnableDebug": false, 5070 "EnableLocalScriptChecks": false, 5071 "EnableRemoteScriptChecks": false, 5072 "EnableSyslog": false, 5073 "EnableUI": false, 5074 "EncryptKey": "hidden", 5075 "EncryptVerifyIncoming": false, 5076 "EncryptVerifyOutgoing": false, 5077 "GRPCAddrs": [], 5078 "GRPCPort": 0, 5079 "HTTPAddrs": [ 5080 "tcp://1.2.3.4:5678", 5081 "unix:///var/run/foo" 5082 ], 5083 "HTTPBlockEndpoints": [], 5084 "HTTPPort": 0, 5085 "HTTPResponseHeaders": {}, 5086 "HTTPSAddrs": [], 5087 "HTTPSPort": 0, 5088 "KeyFile": "hidden", 5089 "LeaveDrainTime": "0s", 5090 "LeaveOnTerm": false, 5091 "LogLevel": "", 5092 "LogFile": "", 5093 "LogRotateBytes": 0, 5094 "LogRotateDuration": "0s", 5095 "NodeID": "", 5096 "NodeMeta": {}, 5097 "NodeName": "", 5098 "NonVotingServer": false, 5099 "PidFile": "", 5100 "PrimaryDatacenter": "", 5101 "RPCAdvertiseAddr": "", 5102 "RPCBindAddr": "", 5103 "RPCHoldTimeout": "0s", 5104 "RPCMaxBurst": 0, 5105 "RPCProtocol": 0, 5106 "RPCRateLimit": 0, 5107 "RaftProtocol": 0, 5108 "RaftSnapshotInterval": "0s", 5109 "RaftSnapshotThreshold": 0, 5110 "ReconnectTimeoutLAN": "0s", 5111 "ReconnectTimeoutWAN": "0s", 5112 "RejoinAfterLeave": false, 5113 "RetryJoinIntervalLAN": "0s", 5114 "RetryJoinIntervalWAN": "0s", 5115 "RetryJoinLAN": [ 5116 "foo=bar key=hidden secret=hidden bang=bar" 5117 ], 5118 "RetryJoinMaxAttemptsLAN": 0, 5119 "RetryJoinMaxAttemptsWAN": 0, 5120 "RetryJoinWAN": [ 5121 "wan_foo=bar wan_key=hidden wan_secret=hidden wan_bang=bar" 5122 ], 5123 "Revision": "", 5124 "SegmentLimit": 0, 5125 "SegmentName": "", 5126 "SegmentNameLimit": 0, 5127 "Segments": [], 5128 "SerfAdvertiseAddrLAN": "tcp://1.2.3.4:5678", 5129 "SerfAdvertiseAddrWAN": "", 5130 "SerfBindAddrLAN": "", 5131 "SerfBindAddrWAN": "", 5132 "SerfPortLAN": 0, 5133 "SerfPortWAN": 0, 5134 "ServerMode": false, 5135 "ServerName": "", 5136 "ServerPort": 0, 5137 "Services": [{ 5138 "Address": "", 5139 "Check": { 5140 "AliasNode": "", 5141 "AliasService": "", 5142 "CheckID": "", 5143 "DeregisterCriticalServiceAfter": "0s", 5144 "DockerContainerID": "", 5145 "GRPC": "", 5146 "GRPCUseTLS": false, 5147 "HTTP": "", 5148 "Header": {}, 5149 "Interval": "0s", 5150 "Method": "", 5151 "Name": "blurb", 5152 "Notes": "", 5153 "ScriptArgs": [], 5154 "Shell": "", 5155 "Status": "", 5156 "TCP": "", 5157 "TLSSkipVerify": false, 5158 "TTL": "0s", 5159 "Timeout": "0s" 5160 }, 5161 "Checks": [], 5162 "Connect": null, 5163 "EnableTagOverride": false, 5164 "ID": "", 5165 "Kind": "", 5166 "Meta": {}, 5167 "Name": "foo", 5168 "Port": 0, 5169 "Proxy": null, 5170 "ProxyDestination": "", 5171 "Tags": [], 5172 "Token": "hidden", 5173 "Weights": { 5174 "Passing": 67, 5175 "Warning": 3 5176 } 5177 }], 5178 "SessionTTLMin": "0s", 5179 "SkipLeaveOnInt": false, 5180 "StartJoinAddrsLAN": [], 5181 "StartJoinAddrsWAN": [], 5182 "SyncCoordinateIntervalMin": "0s", 5183 "SyncCoordinateRateTarget": 0, 5184 "SyslogFacility": "", 5185 "TLSCipherSuites": [], 5186 "TLSMinVersion": "", 5187 "TLSPreferServerCipherSuites": false, 5188 "TaggedAddresses": {}, 5189 "Telemetry": { 5190 "AllowedPrefixes": [], 5191 "BlockedPrefixes": [], 5192 "CirconusAPIApp": "", 5193 "CirconusAPIToken": "hidden", 5194 "CirconusAPIURL": "", 5195 "CirconusBrokerID": "", 5196 "CirconusBrokerSelectTag": "", 5197 "CirconusCheckDisplayName": "", 5198 "CirconusCheckForceMetricActivation": "", 5199 "CirconusCheckID": "", 5200 "CirconusCheckInstanceID": "", 5201 "CirconusCheckSearchTag": "", 5202 "CirconusCheckTags": "", 5203 "CirconusSubmissionInterval": "", 5204 "CirconusSubmissionURL": "", 5205 "DisableHostname": false, 5206 "DogstatsdAddr": "", 5207 "DogstatsdTags": [], 5208 "FilterDefault": false, 5209 "MetricsPrefix": "", 5210 "PrometheusRetentionTime": "0s", 5211 "StatsdAddr": "", 5212 "StatsiteAddr": "" 5213 }, 5214 "TranslateWANAddrs": false, 5215 "UIDir": "", 5216 "UnixSocketGroup": "", 5217 "UnixSocketMode": "", 5218 "UnixSocketUser": "", 5219 "VerifyIncoming": false, 5220 "VerifyIncomingHTTPS": false, 5221 "VerifyIncomingRPC": false, 5222 "VerifyOutgoing": false, 5223 "VerifyServerHostname": false, 5224 "Version": "", 5225 "VersionPrerelease": "", 5226 "Watches": [], 5227 "AllowWriteHTTPFrom": [] 5228 }` 5229 b, err := json.MarshalIndent(rt.Sanitized(), "", " ") 5230 if err != nil { 5231 t.Fatal(err) 5232 } 5233 require.JSONEq(t, rtJSON, string(b)) 5234 } 5235 5236 func TestRuntime_apiAddresses(t *testing.T) { 5237 rt := RuntimeConfig{ 5238 HTTPAddrs: []net.Addr{ 5239 &net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5678}, 5240 &net.UnixAddr{Name: "/var/run/foo"}, 5241 }, 5242 HTTPSAddrs: []net.Addr{ 5243 &net.TCPAddr{IP: net.ParseIP("198.18.0.2"), Port: 5678}, 5244 }} 5245 5246 unixAddrs, httpAddrs, httpsAddrs := rt.apiAddresses(1) 5247 5248 require.Len(t, unixAddrs, 1) 5249 require.Len(t, httpAddrs, 1) 5250 require.Len(t, httpsAddrs, 1) 5251 5252 require.Equal(t, "/var/run/foo", unixAddrs[0]) 5253 require.Equal(t, "198.18.0.1:5678", httpAddrs[0]) 5254 require.Equal(t, "198.18.0.2:5678", httpsAddrs[0]) 5255 } 5256 5257 func TestRuntime_APIConfigHTTPS(t *testing.T) { 5258 rt := RuntimeConfig{ 5259 HTTPAddrs: []net.Addr{ 5260 &net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5678}, 5261 &net.UnixAddr{Name: "/var/run/foo"}, 5262 }, 5263 HTTPSAddrs: []net.Addr{ 5264 &net.TCPAddr{IP: net.ParseIP("198.18.0.2"), Port: 5678}, 5265 }, 5266 Datacenter: "dc-test", 5267 CAFile: "/etc/consul/ca.crt", 5268 CAPath: "/etc/consul/ca.dir", 5269 CertFile: "/etc/consul/server.crt", 5270 KeyFile: "/etc/consul/ssl/server.key", 5271 VerifyOutgoing: false, 5272 } 5273 5274 cfg, err := rt.APIConfig(false) 5275 require.NoError(t, err) 5276 require.Equal(t, "198.18.0.2:5678", cfg.Address) 5277 require.Equal(t, "https", cfg.Scheme) 5278 require.Equal(t, rt.CAFile, cfg.TLSConfig.CAFile) 5279 require.Equal(t, rt.CAPath, cfg.TLSConfig.CAPath) 5280 require.Equal(t, "", cfg.TLSConfig.CertFile) 5281 require.Equal(t, "", cfg.TLSConfig.KeyFile) 5282 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5283 require.Equal(t, true, cfg.TLSConfig.InsecureSkipVerify) 5284 5285 rt.VerifyOutgoing = true 5286 cfg, err = rt.APIConfig(true) 5287 require.NoError(t, err) 5288 require.Equal(t, "198.18.0.2:5678", cfg.Address) 5289 require.Equal(t, "https", cfg.Scheme) 5290 require.Equal(t, rt.CAFile, cfg.TLSConfig.CAFile) 5291 require.Equal(t, rt.CAPath, cfg.TLSConfig.CAPath) 5292 require.Equal(t, rt.CertFile, cfg.TLSConfig.CertFile) 5293 require.Equal(t, rt.KeyFile, cfg.TLSConfig.KeyFile) 5294 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5295 require.Equal(t, false, cfg.TLSConfig.InsecureSkipVerify) 5296 } 5297 5298 func TestRuntime_APIConfigHTTP(t *testing.T) { 5299 rt := RuntimeConfig{ 5300 HTTPAddrs: []net.Addr{ 5301 &net.UnixAddr{Name: "/var/run/foo"}, 5302 &net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5678}, 5303 }, 5304 Datacenter: "dc-test", 5305 } 5306 5307 cfg, err := rt.APIConfig(false) 5308 require.NoError(t, err) 5309 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5310 require.Equal(t, "198.18.0.1:5678", cfg.Address) 5311 require.Equal(t, "http", cfg.Scheme) 5312 require.Equal(t, "", cfg.TLSConfig.CAFile) 5313 require.Equal(t, "", cfg.TLSConfig.CAPath) 5314 require.Equal(t, "", cfg.TLSConfig.CertFile) 5315 require.Equal(t, "", cfg.TLSConfig.KeyFile) 5316 } 5317 5318 func TestRuntime_APIConfigUNIX(t *testing.T) { 5319 rt := RuntimeConfig{ 5320 HTTPAddrs: []net.Addr{ 5321 &net.UnixAddr{Name: "/var/run/foo"}, 5322 }, 5323 Datacenter: "dc-test", 5324 } 5325 5326 cfg, err := rt.APIConfig(false) 5327 require.NoError(t, err) 5328 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5329 require.Equal(t, "unix:///var/run/foo", cfg.Address) 5330 require.Equal(t, "http", cfg.Scheme) 5331 require.Equal(t, "", cfg.TLSConfig.CAFile) 5332 require.Equal(t, "", cfg.TLSConfig.CAPath) 5333 require.Equal(t, "", cfg.TLSConfig.CertFile) 5334 require.Equal(t, "", cfg.TLSConfig.KeyFile) 5335 } 5336 5337 func TestRuntime_APIConfigANYAddrV4(t *testing.T) { 5338 rt := RuntimeConfig{ 5339 HTTPAddrs: []net.Addr{ 5340 &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5678}, 5341 }, 5342 Datacenter: "dc-test", 5343 } 5344 5345 cfg, err := rt.APIConfig(false) 5346 require.NoError(t, err) 5347 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5348 require.Equal(t, "127.0.0.1:5678", cfg.Address) 5349 require.Equal(t, "http", cfg.Scheme) 5350 require.Equal(t, "", cfg.TLSConfig.CAFile) 5351 require.Equal(t, "", cfg.TLSConfig.CAPath) 5352 require.Equal(t, "", cfg.TLSConfig.CertFile) 5353 require.Equal(t, "", cfg.TLSConfig.KeyFile) 5354 } 5355 5356 func TestRuntime_APIConfigANYAddrV6(t *testing.T) { 5357 rt := RuntimeConfig{ 5358 HTTPAddrs: []net.Addr{ 5359 &net.TCPAddr{IP: net.ParseIP("::"), Port: 5678}, 5360 }, 5361 Datacenter: "dc-test", 5362 } 5363 5364 cfg, err := rt.APIConfig(false) 5365 require.NoError(t, err) 5366 require.Equal(t, rt.Datacenter, cfg.Datacenter) 5367 require.Equal(t, "[::1]:5678", cfg.Address) 5368 require.Equal(t, "http", cfg.Scheme) 5369 require.Equal(t, "", cfg.TLSConfig.CAFile) 5370 require.Equal(t, "", cfg.TLSConfig.CAPath) 5371 require.Equal(t, "", cfg.TLSConfig.CertFile) 5372 require.Equal(t, "", cfg.TLSConfig.KeyFile) 5373 } 5374 5375 func TestRuntime_ClientAddress(t *testing.T) { 5376 rt := RuntimeConfig{ 5377 HTTPAddrs: []net.Addr{ 5378 &net.TCPAddr{IP: net.ParseIP("::"), Port: 5678}, 5379 &net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5679}, 5380 &net.UnixAddr{Name: "/var/run/foo", Net: "unix"}, 5381 }, 5382 HTTPSAddrs: []net.Addr{ 5383 &net.TCPAddr{IP: net.ParseIP("::"), Port: 5688}, 5384 &net.TCPAddr{IP: net.ParseIP("198.18.0.1"), Port: 5689}, 5385 }, 5386 } 5387 5388 unix, http, https := rt.ClientAddress() 5389 5390 require.Equal(t, "unix:///var/run/foo", unix) 5391 require.Equal(t, "198.18.0.1:5679", http) 5392 require.Equal(t, "198.18.0.1:5689", https) 5393 } 5394 5395 func TestRuntime_ClientAddressAnyV4(t *testing.T) { 5396 rt := RuntimeConfig{ 5397 HTTPAddrs: []net.Addr{ 5398 &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5678}, 5399 &net.UnixAddr{Name: "/var/run/foo", Net: "unix"}, 5400 }, 5401 HTTPSAddrs: []net.Addr{ 5402 &net.TCPAddr{IP: net.ParseIP("0.0.0.0"), Port: 5688}, 5403 }, 5404 } 5405 5406 unix, http, https := rt.ClientAddress() 5407 5408 require.Equal(t, "unix:///var/run/foo", unix) 5409 require.Equal(t, "127.0.0.1:5678", http) 5410 require.Equal(t, "127.0.0.1:5688", https) 5411 } 5412 5413 func TestRuntime_ClientAddressAnyV6(t *testing.T) { 5414 rt := RuntimeConfig{ 5415 HTTPAddrs: []net.Addr{ 5416 &net.TCPAddr{IP: net.ParseIP("::"), Port: 5678}, 5417 &net.UnixAddr{Name: "/var/run/foo", Net: "unix"}, 5418 }, 5419 HTTPSAddrs: []net.Addr{ 5420 &net.TCPAddr{IP: net.ParseIP("::"), Port: 5688}, 5421 }, 5422 } 5423 5424 unix, http, https := rt.ClientAddress() 5425 5426 require.Equal(t, "unix:///var/run/foo", unix) 5427 require.Equal(t, "[::1]:5678", http) 5428 require.Equal(t, "[::1]:5688", https) 5429 } 5430 5431 func TestRuntime_ToTLSUtilConfig(t *testing.T) { 5432 c := &RuntimeConfig{ 5433 VerifyIncoming: true, 5434 VerifyIncomingRPC: true, 5435 VerifyIncomingHTTPS: true, 5436 VerifyOutgoing: true, 5437 VerifyServerHostname: true, 5438 CAFile: "a", 5439 CAPath: "b", 5440 CertFile: "c", 5441 KeyFile: "d", 5442 NodeName: "e", 5443 ServerName: "f", 5444 DNSDomain: "g", 5445 TLSMinVersion: "tls12", 5446 TLSCipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305}, 5447 TLSPreferServerCipherSuites: true, 5448 EnableAgentTLSForChecks: true, 5449 } 5450 r := c.ToTLSUtilConfig() 5451 require.Equal(t, c.VerifyIncoming, r.VerifyIncoming) 5452 require.Equal(t, c.VerifyIncomingRPC, r.VerifyIncomingRPC) 5453 require.Equal(t, c.VerifyIncomingHTTPS, r.VerifyIncomingHTTPS) 5454 require.Equal(t, c.VerifyOutgoing, r.VerifyOutgoing) 5455 require.Equal(t, c.VerifyServerHostname, r.VerifyServerHostname) 5456 require.Equal(t, c.CAFile, r.CAFile) 5457 require.Equal(t, c.CAPath, r.CAPath) 5458 require.Equal(t, c.CertFile, r.CertFile) 5459 require.Equal(t, c.KeyFile, r.KeyFile) 5460 require.Equal(t, c.NodeName, r.NodeName) 5461 require.Equal(t, c.ServerName, r.ServerName) 5462 require.Equal(t, c.DNSDomain, r.Domain) 5463 require.Equal(t, c.TLSMinVersion, r.TLSMinVersion) 5464 require.Equal(t, c.TLSCipherSuites, r.CipherSuites) 5465 require.Equal(t, c.TLSPreferServerCipherSuites, r.PreferServerCipherSuites) 5466 require.Equal(t, c.EnableAgentTLSForChecks, r.EnableAgentTLSForChecks) 5467 } 5468 5469 func splitIPPort(hostport string) (net.IP, int) { 5470 h, p, err := net.SplitHostPort(hostport) 5471 if err != nil { 5472 panic(err) 5473 } 5474 port, err := strconv.Atoi(p) 5475 if err != nil { 5476 panic(err) 5477 } 5478 return net.ParseIP(h), port 5479 } 5480 5481 func ipAddr(addr string) *net.IPAddr { 5482 return &net.IPAddr{IP: net.ParseIP(addr)} 5483 } 5484 5485 func tcpAddr(addr string) *net.TCPAddr { 5486 ip, port := splitIPPort(addr) 5487 return &net.TCPAddr{IP: ip, Port: port} 5488 } 5489 5490 func udpAddr(addr string) *net.UDPAddr { 5491 ip, port := splitIPPort(addr) 5492 return &net.UDPAddr{IP: ip, Port: port} 5493 } 5494 5495 func unixAddr(addr string) *net.UnixAddr { 5496 if !strings.HasPrefix(addr, "unix://") { 5497 panic("not a unix socket addr: " + addr) 5498 } 5499 return &net.UnixAddr{Net: "unix", Name: addr[len("unix://"):]} 5500 } 5501 5502 func writeFile(path string, data []byte) { 5503 if err := os.MkdirAll(filepath.Dir(path), 0750); err != nil { 5504 panic(err) 5505 } 5506 if err := ioutil.WriteFile(path, data, 0640); err != nil { 5507 panic(err) 5508 } 5509 } 5510 5511 func cleanDir(path string) { 5512 root := path 5513 err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { 5514 if path == root { 5515 return nil 5516 } 5517 return os.RemoveAll(path) 5518 }) 5519 if err != nil { 5520 panic(err) 5521 } 5522 } 5523 5524 func randomString(n int) string { 5525 s := "" 5526 for ; n > 0; n-- { 5527 s += "x" 5528 } 5529 return s 5530 } 5531 5532 func metaPairs(n int, format string) string { 5533 var s []string 5534 for i := 0; i < n; i++ { 5535 switch format { 5536 case "json": 5537 s = append(s, fmt.Sprintf(`"%d":"%d"`, i, i)) 5538 case "hcl": 5539 s = append(s, fmt.Sprintf(`"%d"="%d"`, i, i)) 5540 default: 5541 panic("invalid format: " + format) 5542 } 5543 } 5544 switch format { 5545 case "json": 5546 return strings.Join(s, ",") 5547 case "hcl": 5548 return strings.Join(s, " ") 5549 default: 5550 panic("invalid format: " + format) 5551 } 5552 }