github.com/tommi2day/tnscli@v0.0.0-20240401211958-338fc0647b73/cmd/dns_docker_test.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "os" 8 "time" 9 10 "github.com/tommi2day/tnscli/test" 11 12 "github.com/tommi2day/gomodules/common" 13 "github.com/tommi2day/gomodules/dblib" 14 15 "github.com/ory/dockertest/v3" 16 "github.com/ory/dockertest/v3/docker" 17 ) 18 19 const DNScontainerTimeout = 10 20 const networkName = "dblib-dnsnetwork" 21 22 var dnscontainerName string 23 var dnsContainer *dockertest.Resource 24 var dnsnetwork *dockertest.Network 25 var networkCreated = false 26 var dnsserver = "" 27 var dnsport = 0 28 29 // prepareDNSContainer create a Bind9 Docker Container 30 func prepareDNSContainer() (container *dockertest.Resource, err error) { 31 if os.Getenv("SKIP_DNS") != "" { 32 err = fmt.Errorf("skipping DNS Container in CI environment") 33 return 34 } 35 dnscontainerName = os.Getenv("DNS_CONTAINER_NAME") 36 if dnscontainerName == "" { 37 dnscontainerName = "tnscli-bind9" 38 } 39 var pool *dockertest.Pool 40 pool, err = common.GetDockerPool() 41 if err != nil { 42 return 43 } 44 45 networks, err := pool.NetworksByName(networkName) 46 if err != nil || len(networks) == 0 { 47 dnsnetwork, err = pool.CreateNetwork(networkName, func(options *docker.CreateNetworkOptions) { 48 options.Name = networkName 49 options.CheckDuplicate = true 50 options.IPAM = &docker.IPAMOptions{ 51 Driver: "default", 52 Config: []docker.IPAMConfig{{ 53 Subnet: "172.24.0.0/16", 54 Gateway: "172.24.0.1", 55 }}, 56 } 57 options.EnableIPv6 = false 58 // options.Internal = true 59 }) 60 if err != nil { 61 err = fmt.Errorf("could not create Network: %s:%s", networkName, err) 62 return 63 } 64 networkCreated = true 65 } else { 66 dnsnetwork = &networks[0] 67 } 68 69 vendorImagePrefix := os.Getenv("VENDOR_IMAGE_PREFIX") 70 71 fmt.Printf("Try to build and start docker container %s\n", dnscontainerName) 72 buildArgs := []docker.BuildArg{ 73 { 74 Name: "VENDOR_IMAGE_PREFIX", 75 Value: vendorImagePrefix, 76 }, 77 { 78 Name: "BIND9_VERSION", 79 Value: "9.18", 80 }, 81 } 82 container, err = pool.BuildAndRunWithBuildOptions( 83 &dockertest.BuildOptions{ 84 BuildArgs: buildArgs, 85 ContextDir: test.TestDir + "/docker/dns", 86 Dockerfile: "Dockerfile", 87 }, 88 &dockertest.RunOptions{ 89 Hostname: dnscontainerName, 90 Name: dnscontainerName, 91 Networks: []*dockertest.Network{dnsnetwork}, 92 ExposedPorts: []string{"53/tcp", "53/udp", "953/tcp"}, 93 }, func(config *docker.HostConfig) { 94 // set AutoRemove to true so that stopped container goes away by itself 95 config.AutoRemove = true 96 config.RestartPolicy = docker.RestartPolicy{Name: "no"} 97 }) 98 99 if err != nil { 100 err = fmt.Errorf("error starting dns docker container: %v", err) 101 return 102 } 103 // ip := container.Container.NetworkSettings.Networks[networkName].IPAddress 104 ip := container.GetIPInNetwork(dnsnetwork) 105 if ip != "172.24.0.2" { 106 err = fmt.Errorf("internal ip not as expected: %s", ip) 107 return 108 } 109 pool.MaxWait = DNScontainerTimeout * time.Second 110 dnsserver, dnsport = common.GetContainerHostAndPort(container, "53/tcp") 111 fmt.Printf("Wait to successfully connect to DNS to %s:%d (max %ds)...\n", dnsserver, dnsport, DNScontainerTimeout) 112 start := time.Now() 113 var c net.Conn 114 if err = pool.Retry(func() error { 115 c, err = net.Dial("tcp", fmt.Sprintf("%s:%d", dnsserver, dnsport)) 116 if err != nil { 117 fmt.Printf("Err:%s\n", err) 118 } 119 return err 120 }); err != nil { 121 fmt.Printf("Could not connect to DNS Container: %d", err) 122 return 123 } 124 _ = c.Close() 125 126 // wait 5s to init container 127 time.Sleep(5 * time.Second) 128 elapsed := time.Since(start) 129 fmt.Printf("DNS Container is available after %s\n", elapsed.Round(time.Millisecond)) 130 // test dns 131 r := dblib.SetResolver(dnsserver, dnsport, true) 132 ips, e := r.LookupHost(context.Background(), racaddr) 133 if e != nil || len(ips) == 0 { 134 fmt.Printf("Could not resolve DNS with %s: %v", racaddr, e) 135 return 136 } 137 fmt.Println("DNS Container is ready, host", racaddr, "resolved to", ips[0]) 138 err = nil 139 return 140 } 141 142 func destroyDNSContainer(container *dockertest.Resource) { 143 common.DestroyDockerContainer(container) 144 if networkCreated { 145 _ = dnsnetwork.Close() 146 } 147 }