bootstrap.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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 bootstrap provides functionality to generate bootstrap configuration.
  19. package bootstrap
  20. import (
  21. "encoding/json"
  22. "fmt"
  23. "os"
  24. "google.golang.org/grpc/grpclog"
  25. "google.golang.org/grpc/internal/envconfig"
  26. )
  27. var logger = grpclog.Component("internal/xds")
  28. // Options wraps the parameters used to generate bootstrap configuration.
  29. type Options struct {
  30. // NodeID is the node identifier of the gRPC client/server node in the
  31. // proxyless service mesh.
  32. NodeID string
  33. // ServerURI is the address of the management server.
  34. ServerURI string
  35. // IgnoreResourceDeletion, if true, results in a bootstrap config with the
  36. // `server_features` list containing `ignore_resource_deletion`. This results
  37. // in gRPC ignoring resource deletions from the management server, as per A53.
  38. IgnoreResourceDeletion bool
  39. // ClientDefaultListenerResourceNameTemplate is the default listener
  40. // resource name template to be used on the gRPC client.
  41. ClientDefaultListenerResourceNameTemplate string
  42. // ServerListenerResourceNameTemplate is the listener resource name template
  43. // to be used on the gRPC server.
  44. ServerListenerResourceNameTemplate string
  45. // CertificateProviders is the certificate providers configuration.
  46. CertificateProviders map[string]json.RawMessage
  47. // Authorities is a list of non-default authorities.
  48. //
  49. // In the config, an authority contains {ServerURI, xds-version, creds,
  50. // features, etc}. Note that this fields only has ServerURI (it's a
  51. // map[authority-name]ServerURI). The other fields (version, creds,
  52. // features) are assumed to be the same as the default authority (they can
  53. // be added later if needed).
  54. //
  55. // If the env var corresponding to federation (envconfig.XDSFederation) is
  56. // set, an entry with empty string as the key and empty server config as
  57. // value will be added. This will be used by new style resource names with
  58. // an empty authority.
  59. Authorities map[string]string
  60. }
  61. // CreateFile creates a temporary file with bootstrap contents, based on the
  62. // passed in options, and updates the bootstrap environment variable to point to
  63. // this file.
  64. //
  65. // Returns a cleanup function which will be non-nil if the setup process was
  66. // completed successfully. It is the responsibility of the caller to invoke the
  67. // cleanup function at the end of the test.
  68. func CreateFile(opts Options) (func(), error) {
  69. bootstrapContents, err := Contents(opts)
  70. if err != nil {
  71. return nil, err
  72. }
  73. f, err := os.CreateTemp("", "test_xds_bootstrap_*")
  74. if err != nil {
  75. return nil, fmt.Errorf("failed to created bootstrap file: %v", err)
  76. }
  77. if err := os.WriteFile(f.Name(), bootstrapContents, 0644); err != nil {
  78. return nil, fmt.Errorf("failed to created bootstrap file: %v", err)
  79. }
  80. logger.Infof("Created bootstrap file at %q with contents: %s\n", f.Name(), bootstrapContents)
  81. origBootstrapFileName := envconfig.XDSBootstrapFileName
  82. envconfig.XDSBootstrapFileName = f.Name()
  83. return func() {
  84. os.Remove(f.Name())
  85. envconfig.XDSBootstrapFileName = origBootstrapFileName
  86. }, nil
  87. }
  88. // Contents returns the contents to go into a bootstrap file, environment, or
  89. // configuration passed to xds.NewXDSResolverWithConfigForTesting.
  90. func Contents(opts Options) ([]byte, error) {
  91. cfg := &bootstrapConfig{
  92. XdsServers: []server{
  93. {
  94. ServerURI: opts.ServerURI,
  95. ChannelCreds: []creds{{Type: "insecure"}},
  96. },
  97. },
  98. Node: node{
  99. ID: opts.NodeID,
  100. },
  101. CertificateProviders: opts.CertificateProviders,
  102. ClientDefaultListenerResourceNameTemplate: opts.ClientDefaultListenerResourceNameTemplate,
  103. ServerListenerResourceNameTemplate: opts.ServerListenerResourceNameTemplate,
  104. }
  105. cfg.XdsServers[0].ServerFeatures = append(cfg.XdsServers[0].ServerFeatures, "xds_v3")
  106. if opts.IgnoreResourceDeletion {
  107. cfg.XdsServers[0].ServerFeatures = append(cfg.XdsServers[0].ServerFeatures, "ignore_resource_deletion")
  108. }
  109. auths := make(map[string]authority)
  110. if envconfig.XDSFederation {
  111. // This will end up using the top-level server list for new style
  112. // resources with empty authority.
  113. auths[""] = authority{}
  114. }
  115. for n, auURI := range opts.Authorities {
  116. auths[n] = authority{XdsServers: []server{{
  117. ServerURI: auURI,
  118. ChannelCreds: []creds{{Type: "insecure"}},
  119. ServerFeatures: cfg.XdsServers[0].ServerFeatures,
  120. }}}
  121. }
  122. cfg.Authorities = auths
  123. bootstrapContents, err := json.MarshalIndent(cfg, "", " ")
  124. if err != nil {
  125. return nil, fmt.Errorf("failed to created bootstrap file: %v", err)
  126. }
  127. return bootstrapContents, nil
  128. }
  129. type bootstrapConfig struct {
  130. XdsServers []server `json:"xds_servers,omitempty"`
  131. Node node `json:"node,omitempty"`
  132. CertificateProviders map[string]json.RawMessage `json:"certificate_providers,omitempty"`
  133. ClientDefaultListenerResourceNameTemplate string `json:"client_default_listener_resource_name_template,omitempty"`
  134. ServerListenerResourceNameTemplate string `json:"server_listener_resource_name_template,omitempty"`
  135. Authorities map[string]authority `json:"authorities,omitempty"`
  136. }
  137. type authority struct {
  138. XdsServers []server `json:"xds_servers,omitempty"`
  139. }
  140. type server struct {
  141. ServerURI string `json:"server_uri,omitempty"`
  142. ChannelCreds []creds `json:"channel_creds,omitempty"`
  143. ServerFeatures []string `json:"server_features,omitempty"`
  144. }
  145. type creds struct {
  146. Type string `json:"type,omitempty"`
  147. Config interface{} `json:"config,omitempty"`
  148. }
  149. type node struct {
  150. ID string `json:"id,omitempty"`
  151. }