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