utils.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /*
  2. *
  3. * Copyright 2021 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package googledirectpath
  19. import (
  20. "bytes"
  21. "fmt"
  22. "io"
  23. "net/http"
  24. "net/url"
  25. "sync"
  26. "time"
  27. )
  28. func getFromMetadata(timeout time.Duration, urlStr string) ([]byte, error) {
  29. parsedURL, err := url.Parse(urlStr)
  30. if err != nil {
  31. return nil, err
  32. }
  33. client := &http.Client{Timeout: timeout}
  34. req := &http.Request{
  35. Method: http.MethodGet,
  36. URL: parsedURL,
  37. Header: http.Header{"Metadata-Flavor": {"Google"}},
  38. }
  39. resp, err := client.Do(req)
  40. if err != nil {
  41. return nil, fmt.Errorf("failed communicating with metadata server: %v", err)
  42. }
  43. defer resp.Body.Close()
  44. if resp.StatusCode != http.StatusOK {
  45. return nil, fmt.Errorf("metadata server returned resp with non-OK: %v", resp)
  46. }
  47. body, err := io.ReadAll(resp.Body)
  48. if err != nil {
  49. return nil, fmt.Errorf("failed reading from metadata server: %v", err)
  50. }
  51. return body, nil
  52. }
  53. var (
  54. zone string
  55. zoneOnce sync.Once
  56. )
  57. // Defined as var to be overridden in tests.
  58. var getZone = func(timeout time.Duration) string {
  59. zoneOnce.Do(func() {
  60. qualifiedZone, err := getFromMetadata(timeout, zoneURL)
  61. if err != nil {
  62. logger.Warningf("could not discover instance zone: %v", err)
  63. return
  64. }
  65. i := bytes.LastIndexByte(qualifiedZone, '/')
  66. if i == -1 {
  67. logger.Warningf("could not parse zone from metadata server: %s", qualifiedZone)
  68. return
  69. }
  70. zone = string(qualifiedZone[i+1:])
  71. })
  72. return zone
  73. }
  74. var (
  75. ipv6Capable bool
  76. ipv6CapableOnce sync.Once
  77. )
  78. // Defined as var to be overridden in tests.
  79. var getIPv6Capable = func(timeout time.Duration) bool {
  80. ipv6CapableOnce.Do(func() {
  81. _, err := getFromMetadata(timeout, ipv6URL)
  82. if err != nil {
  83. logger.Warningf("could not discover ipv6 capability: %v", err)
  84. return
  85. }
  86. ipv6Capable = true
  87. })
  88. return ipv6Capable
  89. }