• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.xds;
18 
19 import static com.google.common.base.Preconditions.checkArgument;
20 
21 import com.google.auto.value.AutoValue;
22 import com.google.common.annotations.VisibleForTesting;
23 import com.google.common.collect.ImmutableList;
24 import com.google.common.collect.ImmutableMap;
25 import io.grpc.ChannelCredentials;
26 import io.grpc.Internal;
27 import io.grpc.xds.EnvoyProtoData.Node;
28 import java.util.List;
29 import java.util.Map;
30 import javax.annotation.Nullable;
31 
32 /**
33  * Loads configuration information to bootstrap gRPC's integration of xDS protocol.
34  */
35 @Internal
36 public abstract class Bootstrapper {
37 
38   static final String XDSTP_SCHEME = "xdstp:";
39 
40   /**
41    * Returns system-loaded bootstrap configuration.
42    */
bootstrap()43   public abstract BootstrapInfo bootstrap() throws XdsInitializationException;
44 
45   /**
46    * Returns bootstrap configuration given by the raw data in JSON format.
47    */
bootstrap(Map<String, ?> rawData)48   BootstrapInfo bootstrap(Map<String, ?> rawData) throws XdsInitializationException {
49     throw new UnsupportedOperationException();
50   }
51 
52   /**
53    * Data class containing xDS server information, such as server URI and channel credentials
54    * to be used for communication.
55    */
56   @AutoValue
57   @Internal
58   abstract static class ServerInfo {
target()59     abstract String target();
60 
channelCredentials()61     abstract ChannelCredentials channelCredentials();
62 
ignoreResourceDeletion()63     abstract boolean ignoreResourceDeletion();
64 
65     @VisibleForTesting
create( String target, ChannelCredentials channelCredentials)66     static ServerInfo create(
67         String target, ChannelCredentials channelCredentials) {
68       return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials, false);
69     }
70 
71     @VisibleForTesting
create( String target, ChannelCredentials channelCredentials, boolean ignoreResourceDeletion)72     static ServerInfo create(
73         String target, ChannelCredentials channelCredentials,
74         boolean ignoreResourceDeletion) {
75       return new AutoValue_Bootstrapper_ServerInfo(target, channelCredentials,
76           ignoreResourceDeletion);
77     }
78   }
79 
80   /**
81    * Data class containing Certificate provider information: the plugin-name and an opaque
82    * Map that represents the config for that plugin.
83    */
84   @AutoValue
85   @Internal
86   public abstract static class CertificateProviderInfo {
pluginName()87     public abstract String pluginName();
88 
config()89     public abstract ImmutableMap<String, ?> config();
90 
91     @VisibleForTesting
create(String pluginName, Map<String, ?> config)92     public static CertificateProviderInfo create(String pluginName, Map<String, ?> config) {
93       return new AutoValue_Bootstrapper_CertificateProviderInfo(
94           pluginName, ImmutableMap.copyOf(config));
95     }
96   }
97 
98   @AutoValue
99   abstract static class AuthorityInfo {
100 
101     /**
102      * A template for the name of the Listener resource to subscribe to for a gRPC client
103      * channel. Used only when the channel is created using an "xds:" URI with this authority
104      * name.
105      *
106      * <p>The token "%s", if present in this string, will be replaced with %-encoded
107      * service authority (i.e., the path part of the target URI used to create the gRPC channel).
108      *
109      * <p>Return value must start with {@code "xdstp://<authority_name>/"}.
110      */
clientListenerResourceNameTemplate()111     abstract String clientListenerResourceNameTemplate();
112 
113     /**
114      * Ordered list of xDS servers to contact for this authority.
115      *
116      * <p>If the same server is listed in multiple authorities, the entries will be de-duped (i.e.,
117      * resources for both authorities will be fetched on the same ADS stream).
118      *
119      * <p>Defaults to the top-level server list {@link BootstrapInfo#servers()}. Must not be empty.
120      */
xdsServers()121     abstract ImmutableList<ServerInfo> xdsServers();
122 
create( String clientListenerResourceNameTemplate, List<ServerInfo> xdsServers)123     static AuthorityInfo create(
124         String clientListenerResourceNameTemplate, List<ServerInfo> xdsServers) {
125       checkArgument(!xdsServers.isEmpty(), "xdsServers must not be empty");
126       return new AutoValue_Bootstrapper_AuthorityInfo(
127           clientListenerResourceNameTemplate, ImmutableList.copyOf(xdsServers));
128     }
129   }
130 
131   /**
132    * Data class containing the results of reading bootstrap.
133    */
134   @AutoValue
135   @Internal
136   public abstract static class BootstrapInfo {
137     /** Returns the list of xDS servers to be connected to. Must not be empty. */
servers()138     abstract ImmutableList<ServerInfo> servers();
139 
140     /** Returns the node identifier to be included in xDS requests. */
node()141     public abstract Node node();
142 
143     /** Returns the cert-providers config map. */
144     @Nullable
certProviders()145     public abstract ImmutableMap<String, CertificateProviderInfo> certProviders();
146 
147     /**
148      * A template for the name of the Listener resource to subscribe to for a gRPC server.
149      *
150      * <p>If starts with "xdstp:", will be interpreted as a new-style name, in which case the
151      * authority of the URI will be used to select the relevant configuration in the
152      * "authorities" map. The token "%s", if present in this string, will be replaced with
153      * the IP and port on which the server is listening. If the template starts with "xdstp:",
154      * the replaced string will be %-encoded.
155      *
156      * <p>There is no default; if unset, xDS-based server creation fails.
157      */
158     @Nullable
serverListenerResourceNameTemplate()159     public abstract String serverListenerResourceNameTemplate();
160 
161     /**
162      * A template for the name of the Listener resource to subscribe to for a gRPC client channel.
163      * Used only when the channel is created with an "xds:" URI with no authority.
164      *
165      * <p>If starts with "xdstp:", will be interpreted as a new-style name, in which case the
166      * authority of the URI will be used to select the relevant configuration in the "authorities"
167      * map.
168      *
169      * <p>The token "%s", if present in this string, will be replaced with the service authority
170      * (i.e., the path part of the target URI used to create the gRPC channel). If the template
171      * starts with "xdstp:", the replaced string will be %-encoded.
172      *
173      * <p>Defaults to {@code "%s"}.
174      */
clientDefaultListenerResourceNameTemplate()175     abstract String clientDefaultListenerResourceNameTemplate();
176 
177     /**
178      * A map of authority name to corresponding configuration.
179      *
180      * <p>This is used in the following cases:
181      *
182      * <ul>
183      * <li>A gRPC client channel is created using an "xds:" URI that includes  an
184      * authority.</li>
185      *
186      * <li>A gRPC client channel is created using an "xds:" URI with no authority,
187      * but the "client_default_listener_resource_name_template" field above turns it into an
188      * "xdstp:" URI.</li>
189      *
190      * <li>A gRPC server is created and the "server_listener_resource_name_template" field is an
191      * "xdstp:" URI.</li>
192      * </ul>
193      *
194      * <p>In any of those cases, it is an error if the specified authority is not present in this
195      * map.
196      *
197      * <p>Defaults to an empty map.
198      */
authorities()199     abstract ImmutableMap<String, AuthorityInfo> authorities();
200 
201     @VisibleForTesting
builder()202     static Builder builder() {
203       return new AutoValue_Bootstrapper_BootstrapInfo.Builder()
204           .clientDefaultListenerResourceNameTemplate("%s")
205           .authorities(ImmutableMap.<String, AuthorityInfo>of());
206     }
207 
208     @AutoValue.Builder
209     @VisibleForTesting
210     abstract static class Builder {
211 
servers(List<ServerInfo> servers)212       abstract Builder servers(List<ServerInfo> servers);
213 
node(Node node)214       abstract Builder node(Node node);
215 
certProviders(@ullable Map<String, CertificateProviderInfo> certProviders)216       abstract Builder certProviders(@Nullable Map<String, CertificateProviderInfo> certProviders);
217 
serverListenerResourceNameTemplate( @ullable String serverListenerResourceNameTemplate)218       abstract Builder serverListenerResourceNameTemplate(
219           @Nullable String serverListenerResourceNameTemplate);
220 
clientDefaultListenerResourceNameTemplate( String clientDefaultListenerResourceNameTemplate)221       abstract Builder clientDefaultListenerResourceNameTemplate(
222           String clientDefaultListenerResourceNameTemplate);
223 
authorities(Map<String, AuthorityInfo> authorities)224       abstract Builder authorities(Map<String, AuthorityInfo> authorities);
225 
build()226       abstract BootstrapInfo build();
227     }
228   }
229 }
230