example_tsnet_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package tsnet_test
  4. import (
  5. "flag"
  6. "fmt"
  7. "log"
  8. "net/http"
  9. "os"
  10. "path/filepath"
  11. "tailscale.com/tsnet"
  12. )
  13. // ExampleServer shows you how to construct a ready-to-use tsnet instance.
  14. func ExampleServer() {
  15. srv := new(tsnet.Server)
  16. if err := srv.Start(); err != nil {
  17. log.Fatalf("can't start tsnet server: %v", err)
  18. }
  19. defer srv.Close()
  20. }
  21. // ExampleServer_hostname shows you how to set a tsnet server's hostname.
  22. //
  23. // This setting lets you control the host name of your program on your
  24. // tailnet. By default this will be the name of your program (such as foo
  25. // for a program stored at /usr/local/bin/foo). You can also override this
  26. // by setting the Hostname field.
  27. func ExampleServer_hostname() {
  28. srv := &tsnet.Server{
  29. Hostname: "kirito",
  30. }
  31. // do something with srv
  32. _ = srv
  33. }
  34. // ExampleServer_dir shows you how to configure the persistent directory for
  35. // a tsnet application. This is where the Tailscale node information is stored
  36. // so that your application can reconnect to your tailnet when the application
  37. // is restarted.
  38. //
  39. // By default, tsnet will store data in your user configuration directory based
  40. // on the name of the binary. Note that this folder must already exist or tsnet
  41. // calls will fail.
  42. func ExampleServer_dir() {
  43. dir := filepath.Join("/data", "tsnet")
  44. if err := os.MkdirAll(dir, 0700); err != nil {
  45. log.Fatal(err)
  46. }
  47. srv := &tsnet.Server{
  48. Dir: dir,
  49. }
  50. // do something with srv
  51. _ = srv
  52. }
  53. // ExampleServer_multipleInstances shows you how to configure multiple instances
  54. // of tsnet per program. This allows you to have multiple Tailscale nodes in the
  55. // same process/container.
  56. func ExampleServer_multipleInstances() {
  57. baseDir := "/data"
  58. var servers []*tsnet.Server
  59. for _, hostname := range []string{"ichika", "nino", "miku", "yotsuba", "itsuki"} {
  60. os.MkdirAll(filepath.Join(baseDir, hostname), 0700)
  61. srv := &tsnet.Server{
  62. Hostname: hostname,
  63. AuthKey: os.Getenv("TS_AUTHKEY"),
  64. Ephemeral: true,
  65. Dir: filepath.Join(baseDir, hostname),
  66. }
  67. if err := srv.Start(); err != nil {
  68. log.Fatalf("can't start tsnet server: %v", err)
  69. }
  70. servers = append(servers, srv)
  71. }
  72. // When you're done, close the instances
  73. defer func() {
  74. for _, srv := range servers {
  75. srv.Close()
  76. }
  77. }()
  78. }
  79. // ExampleServer_ignoreLogsSometimes shows you how to ignore all of the log messages
  80. // written by a tsnet instance, but allows you to opt-into them if a command-line
  81. // flag is set.
  82. func ExampleServer_ignoreLogsSometimes() {
  83. tsnetVerbose := flag.Bool("tsnet-verbose", false, "if set, verbosely log tsnet information")
  84. hostname := flag.String("tsnet-hostname", "hikari", "hostname to use on the tailnet")
  85. srv := &tsnet.Server{
  86. Hostname: *hostname,
  87. }
  88. if *tsnetVerbose {
  89. srv.Logf = log.New(os.Stderr, fmt.Sprintf("[tsnet:%s] ", *hostname), log.LstdFlags).Printf
  90. }
  91. }
  92. // ExampleServer_HTTPClient shows you how to make HTTP requests over your tailnet.
  93. //
  94. // If you want to make outgoing HTTP connections to resources on your tailnet, use
  95. // the HTTP client that the tsnet.Server exposes.
  96. func ExampleServer_HTTPClient() {
  97. srv := &tsnet.Server{}
  98. cli := srv.HTTPClient()
  99. resp, err := cli.Get("https://hello.ts.net")
  100. if resp == nil {
  101. log.Fatal(err)
  102. }
  103. // do something with resp
  104. _ = resp
  105. }
  106. // ExampleServer_Start demonstrates the Start method, which should be called if
  107. // you need to explicitly start it. Note that the Start method is implicitly
  108. // called if needed.
  109. func ExampleServer_Start() {
  110. srv := new(tsnet.Server)
  111. if err := srv.Start(); err != nil {
  112. log.Fatal(err)
  113. }
  114. // Be sure to close the server instance at some point. It will stay open until
  115. // either the OS process ends or the server is explicitly closed.
  116. defer srv.Close()
  117. }
  118. // ExampleServer_Listen shows you how to create a TCP listener on your tailnet and
  119. // then makes an HTTP server on top of that.
  120. func ExampleServer_Listen() {
  121. srv := &tsnet.Server{
  122. Hostname: "tadaima",
  123. }
  124. ln, err := srv.Listen("tcp", ":80")
  125. if err != nil {
  126. log.Fatal(err)
  127. }
  128. log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  129. fmt.Fprintln(w, "Hi there! Welcome to the tailnet!")
  130. })))
  131. }
  132. // ExampleServer_ListenTLS shows you how to create a TCP listener on your tailnet and
  133. // then makes an HTTPS server on top of that.
  134. func ExampleServer_ListenTLS() {
  135. srv := &tsnet.Server{
  136. Hostname: "aegis",
  137. }
  138. ln, err := srv.ListenTLS("tcp", ":443")
  139. if err != nil {
  140. log.Fatal(err)
  141. }
  142. log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  143. fmt.Fprintln(w, "Hi there! Welcome to the tailnet!")
  144. })))
  145. }
  146. // ExampleServer_ListenFunnel shows you how to create an HTTPS service on both your tailnet
  147. // and the public internet via Funnel.
  148. func ExampleServer_ListenFunnel() {
  149. srv := &tsnet.Server{
  150. Hostname: "ophion",
  151. }
  152. ln, err := srv.ListenFunnel("tcp", ":443")
  153. if err != nil {
  154. log.Fatal(err)
  155. }
  156. log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  157. fmt.Fprintln(w, "Hi there! Welcome to the tailnet!")
  158. })))
  159. }
  160. // ExampleServer_ListenFunnel_funnelOnly shows you how to create a funnel-only HTTPS service.
  161. func ExampleServer_ListenFunnel_funnelOnly() {
  162. srv := new(tsnet.Server)
  163. srv.Hostname = "ophion"
  164. ln, err := srv.ListenFunnel("tcp", ":443", tsnet.FunnelOnly())
  165. if err != nil {
  166. log.Fatal(err)
  167. }
  168. log.Fatal(http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  169. fmt.Fprintln(w, "Hi there! Welcome to the tailnet!")
  170. })))
  171. }