async-grpc-xds 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/async/grpc/xds/client_side_weighted_round_robin.rb +53 -0
- data/lib/async/grpc/xds/cluster.rb +71 -0
- data/lib/async/grpc/xds/control_plane.rb +10 -7
- data/lib/async/grpc/xds/discovery_client.rb +5 -2
- data/lib/async/grpc/xds/endpoint.rb +102 -0
- data/lib/async/grpc/xds/version.rb +1 -1
- data/lib/async/grpc/xds.rb +3 -1
- data/lib/envoy/config/common/mutation_rules/v3/mutation_rules_pb.rb +33 -0
- data/lib/envoy/config/route/v3/route_components_pb.rb +108 -0
- data/lib/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin_pb.rb +30 -0
- data/lib/envoy/extensions/load_balancing_policies/common/v3/common_pb.rb +41 -0
- data/lib/envoy/type/tracing/v3/custom_tag_pb.rb +31 -0
- data/lib/xds/data/orca/v3/orca_load_report_pb.rb +24 -0
- data/lib/xds/service/orca/v3/open_rca_service.rb +23 -0
- data/lib/xds/service/orca/v3/orca_pb.rb +25 -0
- data/proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto +113 -0
- data/proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto +96 -0
- data/proto/envoy/extensions/load_balancing_policies/common/v3/common.proto +188 -0
- data/proto/envoy/type/tracing/v3/custom_tag.proto +109 -0
- data/proto/readme.md +3 -0
- data/proto/xds/data/orca/v3/orca_load_report.proto +58 -0
- data/proto/xds/service/orca/v3/orca.proto +36 -0
- data/readme.md +6 -0
- data/releases.md +6 -0
- data/xds/test/async/grpc/xds/control_plane.rb +0 -1
- data.tar.gz.sig +0 -0
- metadata +18 -2
- metadata.gz.sig +0 -0
- data/lib/async/grpc/xds/resource_builder.rb +0 -177
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package envoy.type.tracing.v3;
|
|
4
|
+
|
|
5
|
+
import "envoy/type/metadata/v3/metadata.proto";
|
|
6
|
+
|
|
7
|
+
import "udpa/annotations/status.proto";
|
|
8
|
+
import "udpa/annotations/versioning.proto";
|
|
9
|
+
import "validate/validate.proto";
|
|
10
|
+
|
|
11
|
+
option java_package = "io.envoyproxy.envoy.type.tracing.v3";
|
|
12
|
+
option java_outer_classname = "CustomTagProto";
|
|
13
|
+
option java_multiple_files = true;
|
|
14
|
+
option go_package = "github.com/envoyproxy/go-control-plane/envoy/type/tracing/v3;tracingv3";
|
|
15
|
+
option (udpa.annotations.file_status).package_version_status = ACTIVE;
|
|
16
|
+
|
|
17
|
+
// [#protodoc-title: Custom Tag]
|
|
18
|
+
|
|
19
|
+
// Describes custom tags for the active span.
|
|
20
|
+
// [#next-free-field: 7]
|
|
21
|
+
message CustomTag {
|
|
22
|
+
option (udpa.annotations.versioning).previous_message_type = "envoy.type.tracing.v2.CustomTag";
|
|
23
|
+
|
|
24
|
+
// Literal type custom tag with static value for the tag value.
|
|
25
|
+
message Literal {
|
|
26
|
+
option (udpa.annotations.versioning).previous_message_type =
|
|
27
|
+
"envoy.type.tracing.v2.CustomTag.Literal";
|
|
28
|
+
|
|
29
|
+
// Static literal value to populate the tag value.
|
|
30
|
+
string value = 1 [(validate.rules).string = {min_len: 1}];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Environment type custom tag with environment name and default value.
|
|
34
|
+
message Environment {
|
|
35
|
+
option (udpa.annotations.versioning).previous_message_type =
|
|
36
|
+
"envoy.type.tracing.v2.CustomTag.Environment";
|
|
37
|
+
|
|
38
|
+
// Environment variable name to obtain the value to populate the tag value.
|
|
39
|
+
string name = 1 [(validate.rules).string = {min_len: 1}];
|
|
40
|
+
|
|
41
|
+
// When the environment variable is not found,
|
|
42
|
+
// the tag value will be populated with this default value if specified,
|
|
43
|
+
// otherwise no tag will be populated.
|
|
44
|
+
string default_value = 2;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Header type custom tag with header name and default value.
|
|
48
|
+
message Header {
|
|
49
|
+
option (udpa.annotations.versioning).previous_message_type =
|
|
50
|
+
"envoy.type.tracing.v2.CustomTag.Header";
|
|
51
|
+
|
|
52
|
+
// Header name to obtain the value to populate the tag value.
|
|
53
|
+
string name = 1
|
|
54
|
+
[(validate.rules).string = {min_len: 1 well_known_regex: HTTP_HEADER_NAME strict: false}];
|
|
55
|
+
|
|
56
|
+
// When the header does not exist,
|
|
57
|
+
// the tag value will be populated with this default value if specified,
|
|
58
|
+
// otherwise no tag will be populated.
|
|
59
|
+
string default_value = 2;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Metadata type custom tag using
|
|
63
|
+
// :ref:`MetadataKey <envoy_v3_api_msg_type.metadata.v3.MetadataKey>` to retrieve the protobuf value
|
|
64
|
+
// from :ref:`Metadata <envoy_v3_api_msg_config.core.v3.Metadata>`, and populate the tag value with
|
|
65
|
+
// `the canonical JSON <https://developers.google.com/protocol-buffers/docs/proto3#json>`_
|
|
66
|
+
// representation of it.
|
|
67
|
+
message Metadata {
|
|
68
|
+
option (udpa.annotations.versioning).previous_message_type =
|
|
69
|
+
"envoy.type.tracing.v2.CustomTag.Metadata";
|
|
70
|
+
|
|
71
|
+
// Specify what kind of metadata to obtain tag value from.
|
|
72
|
+
metadata.v3.MetadataKind kind = 1;
|
|
73
|
+
|
|
74
|
+
// Metadata key to define the path to retrieve the tag value.
|
|
75
|
+
metadata.v3.MetadataKey metadata_key = 2;
|
|
76
|
+
|
|
77
|
+
// When no valid metadata is found,
|
|
78
|
+
// the tag value would be populated with this default value if specified,
|
|
79
|
+
// otherwise no tag would be populated.
|
|
80
|
+
string default_value = 3;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Used to populate the tag name.
|
|
84
|
+
string tag = 1 [(validate.rules).string = {min_len: 1}];
|
|
85
|
+
|
|
86
|
+
// Used to specify what kind of custom tag.
|
|
87
|
+
oneof type {
|
|
88
|
+
option (validate.required) = true;
|
|
89
|
+
|
|
90
|
+
// A literal custom tag.
|
|
91
|
+
Literal literal = 2;
|
|
92
|
+
|
|
93
|
+
// An environment custom tag.
|
|
94
|
+
Environment environment = 3;
|
|
95
|
+
|
|
96
|
+
// A request header custom tag.
|
|
97
|
+
Header request_header = 4;
|
|
98
|
+
|
|
99
|
+
// A custom tag to obtain tag value from the metadata.
|
|
100
|
+
Metadata metadata = 5;
|
|
101
|
+
|
|
102
|
+
// Custom tag value.
|
|
103
|
+
//
|
|
104
|
+
// The same :ref:`format specifier <config_access_log_format>` as used for
|
|
105
|
+
// :ref:`HTTP access logging <config_access_log>` applies here, however
|
|
106
|
+
// unknown specifier values are replaced with the empty string instead of ``-``.
|
|
107
|
+
string value = 6;
|
|
108
|
+
}
|
|
109
|
+
}
|
data/proto/readme.md
CHANGED
|
@@ -15,6 +15,9 @@ These files come from [envoyproxy/data-plane-api](https://github.com/envoyproxy/
|
|
|
15
15
|
- `envoy/config/route/v3/` - Route definitions (RDS)
|
|
16
16
|
- `envoy/config/core/v3/` - Core types (Node, Address, etc.)
|
|
17
17
|
- `envoy/extensions/transport_sockets/tls/v3/` - TLS/Secret definitions (SDS)
|
|
18
|
+
- `envoy/extensions/load_balancing_policies/` - Typed load-balancing policy definitions
|
|
19
|
+
- `xds/data/orca/v3/` - ORCA load reports
|
|
20
|
+
- `xds/service/orca/v3/` - Out-of-band ORCA reporting service
|
|
18
21
|
- `google/protobuf/` - Google protobuf well-known types
|
|
19
22
|
|
|
20
23
|
## Updating
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package xds.data.orca.v3;
|
|
4
|
+
|
|
5
|
+
option java_outer_classname = "OrcaLoadReportProto";
|
|
6
|
+
option java_multiple_files = true;
|
|
7
|
+
option java_package = "com.github.xds.data.orca.v3";
|
|
8
|
+
option go_package = "github.com/cncf/xds/go/xds/data/orca/v3";
|
|
9
|
+
|
|
10
|
+
import "validate/validate.proto";
|
|
11
|
+
|
|
12
|
+
// See section `ORCA load report format` of the design document in
|
|
13
|
+
// https://github.com/envoyproxy/envoy/issues/6614.
|
|
14
|
+
|
|
15
|
+
message OrcaLoadReport {
|
|
16
|
+
// CPU utilization expressed as a fraction of available CPU resources. This
|
|
17
|
+
// should be derived from the latest sample or measurement. The value may be
|
|
18
|
+
// larger than 1.0 when the usage exceeds the reporter dependent notion of
|
|
19
|
+
// soft limits.
|
|
20
|
+
double cpu_utilization = 1 [(validate.rules).double.gte = 0];
|
|
21
|
+
|
|
22
|
+
// Memory utilization expressed as a fraction of available memory
|
|
23
|
+
// resources. This should be derived from the latest sample or measurement.
|
|
24
|
+
double mem_utilization = 2 [(validate.rules).double.gte = 0, (validate.rules).double.lte = 1];
|
|
25
|
+
|
|
26
|
+
// Total RPS being served by an endpoint. This should cover all services that an endpoint is
|
|
27
|
+
// responsible for.
|
|
28
|
+
// Deprecated -- use ``rps_fractional`` field instead.
|
|
29
|
+
uint64 rps = 3 [deprecated = true];
|
|
30
|
+
|
|
31
|
+
// Application specific requests costs. Each value is an absolute cost (e.g. 3487 bytes of
|
|
32
|
+
// storage) associated with the request.
|
|
33
|
+
map<string, double> request_cost = 4;
|
|
34
|
+
|
|
35
|
+
// Resource utilization values. Each value is expressed as a fraction of total resources
|
|
36
|
+
// available, derived from the latest sample or measurement.
|
|
37
|
+
map<string, double> utilization = 5
|
|
38
|
+
[(validate.rules).map.values.double.gte = 0, (validate.rules).map.values.double.lte = 1];
|
|
39
|
+
|
|
40
|
+
// Total RPS being served by an endpoint. This should cover all services that an endpoint is
|
|
41
|
+
// responsible for.
|
|
42
|
+
double rps_fractional = 6 [(validate.rules).double.gte = 0];
|
|
43
|
+
|
|
44
|
+
// Total EPS (errors/second) being served by an endpoint. This should cover
|
|
45
|
+
// all services that an endpoint is responsible for.
|
|
46
|
+
double eps = 7 [(validate.rules).double.gte = 0];
|
|
47
|
+
|
|
48
|
+
// Application specific opaque metrics.
|
|
49
|
+
map<string, double> named_metrics = 8;
|
|
50
|
+
|
|
51
|
+
// Application specific utilization expressed as a fraction of available
|
|
52
|
+
// resources. For example, an application may report the max of CPU and memory
|
|
53
|
+
// utilization for better load balancing if it is both CPU and memory bound.
|
|
54
|
+
// This should be derived from the latest sample or measurement.
|
|
55
|
+
// The value may be larger than 1.0 when the usage exceeds the reporter
|
|
56
|
+
// dependent notion of soft limits.
|
|
57
|
+
double application_utilization = 9 [(validate.rules).double.gte = 0];
|
|
58
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package xds.service.orca.v3;
|
|
4
|
+
|
|
5
|
+
option java_outer_classname = "OrcaProto";
|
|
6
|
+
option java_multiple_files = true;
|
|
7
|
+
option java_package = "com.github.xds.service.orca.v3";
|
|
8
|
+
option go_package = "github.com/cncf/xds/go/xds/service/orca/v3";
|
|
9
|
+
|
|
10
|
+
import "xds/data/orca/v3/orca_load_report.proto";
|
|
11
|
+
|
|
12
|
+
import "google/protobuf/duration.proto";
|
|
13
|
+
|
|
14
|
+
// See section `Out-of-band (OOB) reporting` of the design document in
|
|
15
|
+
// :ref:`https://github.com/envoyproxy/envoy/issues/6614`.
|
|
16
|
+
|
|
17
|
+
// Out-of-band (OOB) load reporting service for the additional load reporting
|
|
18
|
+
// agent that does not sit in the request path. Reports are periodically sampled
|
|
19
|
+
// with sufficient frequency to provide temporal association with requests.
|
|
20
|
+
// OOB reporting compensates the limitation of in-band reporting in revealing
|
|
21
|
+
// costs for backends that do not provide a steady stream of telemetry such as
|
|
22
|
+
// long running stream operations and zero QPS services. This is a server
|
|
23
|
+
// streaming service, client needs to terminate current RPC and initiate
|
|
24
|
+
// a new call to change backend reporting frequency.
|
|
25
|
+
service OpenRcaService {
|
|
26
|
+
rpc StreamCoreMetrics(OrcaLoadReportRequest) returns (stream xds.data.orca.v3.OrcaLoadReport);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
message OrcaLoadReportRequest {
|
|
30
|
+
// Interval for generating Open RCA core metric responses.
|
|
31
|
+
google.protobuf.Duration report_interval = 1;
|
|
32
|
+
// Request costs to collect. If this is empty, all known requests costs tracked by
|
|
33
|
+
// the load reporting agent will be returned. This provides an opportunity for
|
|
34
|
+
// the client to selectively obtain a subset of tracked costs.
|
|
35
|
+
repeated string request_cost_names = 2;
|
|
36
|
+
}
|
data/readme.md
CHANGED
|
@@ -26,6 +26,12 @@ docker compose -f xds/docker-compose.yaml up --build --exit-code-from tests
|
|
|
26
26
|
|
|
27
27
|
Please see the [project releases](https://socketry.github.io/async-grpc-xds/releases/index) for all releases.
|
|
28
28
|
|
|
29
|
+
### v0.2.0
|
|
30
|
+
|
|
31
|
+
- Add ORCA load reporting messages, service interface, and client-side weighted-round-robin resources.
|
|
32
|
+
- Support endpoint hostnames in generated EDS resources.
|
|
33
|
+
- Replace the general resource builder with focused cluster and endpoint builders.
|
|
34
|
+
|
|
29
35
|
### v0.1.0
|
|
30
36
|
|
|
31
37
|
- Add complete documentation coverage for the public xDS API.
|
data/releases.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Releases
|
|
2
2
|
|
|
3
|
+
## v0.2.0
|
|
4
|
+
|
|
5
|
+
- Add ORCA load reporting messages, service interface, and client-side weighted-round-robin resources.
|
|
6
|
+
- Support endpoint hostnames in generated EDS resources.
|
|
7
|
+
- Replace the general resource builder with focused cluster and endpoint builders.
|
|
8
|
+
|
|
3
9
|
## v0.1.0
|
|
4
10
|
|
|
5
11
|
- Add complete documentation coverage for the public xDS API.
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: async-grpc-xds
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Samuel Williams
|
|
@@ -131,12 +131,14 @@ files:
|
|
|
131
131
|
- lib/async/grpc/xds.rb
|
|
132
132
|
- lib/async/grpc/xds/ads_stream.rb
|
|
133
133
|
- lib/async/grpc/xds/client.rb
|
|
134
|
+
- lib/async/grpc/xds/client_side_weighted_round_robin.rb
|
|
135
|
+
- lib/async/grpc/xds/cluster.rb
|
|
134
136
|
- lib/async/grpc/xds/context.rb
|
|
135
137
|
- lib/async/grpc/xds/control_plane.rb
|
|
136
138
|
- lib/async/grpc/xds/discovery_client.rb
|
|
139
|
+
- lib/async/grpc/xds/endpoint.rb
|
|
137
140
|
- lib/async/grpc/xds/health_checker.rb
|
|
138
141
|
- lib/async/grpc/xds/load_balancer.rb
|
|
139
|
-
- lib/async/grpc/xds/resource_builder.rb
|
|
140
142
|
- lib/async/grpc/xds/resource_cache.rb
|
|
141
143
|
- lib/async/grpc/xds/resources.rb
|
|
142
144
|
- lib/async/grpc/xds/server.rb
|
|
@@ -148,6 +150,7 @@ files:
|
|
|
148
150
|
- lib/envoy/config/cluster/v3/cluster_pb.rb
|
|
149
151
|
- lib/envoy/config/cluster/v3/filter_pb.rb
|
|
150
152
|
- lib/envoy/config/cluster/v3/outlier_detection_pb.rb
|
|
153
|
+
- lib/envoy/config/common/mutation_rules/v3/mutation_rules_pb.rb
|
|
151
154
|
- lib/envoy/config/core/v3/address_pb.rb
|
|
152
155
|
- lib/envoy/config/core/v3/backoff_pb.rb
|
|
153
156
|
- lib/envoy/config/core/v3/base_pb.rb
|
|
@@ -170,6 +173,9 @@ files:
|
|
|
170
173
|
- lib/envoy/config/endpoint/v3/endpoint_components_pb.rb
|
|
171
174
|
- lib/envoy/config/endpoint/v3/endpoint_pb.rb
|
|
172
175
|
- lib/envoy/config/endpoint/v3/load_report_pb.rb
|
|
176
|
+
- lib/envoy/config/route/v3/route_components_pb.rb
|
|
177
|
+
- lib/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin_pb.rb
|
|
178
|
+
- lib/envoy/extensions/load_balancing_policies/common/v3/common_pb.rb
|
|
173
179
|
- lib/envoy/service/discovery/v3/ads_pb.rb
|
|
174
180
|
- lib/envoy/service/discovery/v3/aggregated_discovery_service.rb
|
|
175
181
|
- lib/envoy/service/discovery/v3/discovery_pb.rb
|
|
@@ -186,6 +192,7 @@ files:
|
|
|
186
192
|
- lib/envoy/type/matcher/v3/struct_pb.rb
|
|
187
193
|
- lib/envoy/type/matcher/v3/value_pb.rb
|
|
188
194
|
- lib/envoy/type/metadata/v3/metadata_pb.rb
|
|
195
|
+
- lib/envoy/type/tracing/v3/custom_tag_pb.rb
|
|
189
196
|
- lib/envoy/type/v3/hash_policy_pb.rb
|
|
190
197
|
- lib/envoy/type/v3/http_pb.rb
|
|
191
198
|
- lib/envoy/type/v3/http_status_pb.rb
|
|
@@ -217,6 +224,9 @@ files:
|
|
|
217
224
|
- lib/xds/core/v3/resource_locator_pb.rb
|
|
218
225
|
- lib/xds/core/v3/resource_name_pb.rb
|
|
219
226
|
- lib/xds/core/v3/resource_pb.rb
|
|
227
|
+
- lib/xds/data/orca/v3/orca_load_report_pb.rb
|
|
228
|
+
- lib/xds/service/orca/v3/open_rca_service.rb
|
|
229
|
+
- lib/xds/service/orca/v3/orca_pb.rb
|
|
220
230
|
- lib/xds/type/matcher/v3/domain_pb.rb
|
|
221
231
|
- lib/xds/type/matcher/v3/http_inputs_pb.rb
|
|
222
232
|
- lib/xds/type/matcher/v3/ip_pb.rb
|
|
@@ -234,6 +244,7 @@ files:
|
|
|
234
244
|
- proto/envoy/config/cluster/v3/cluster.proto
|
|
235
245
|
- proto/envoy/config/cluster/v3/filter.proto
|
|
236
246
|
- proto/envoy/config/cluster/v3/outlier_detection.proto
|
|
247
|
+
- proto/envoy/config/common/mutation_rules/v3/mutation_rules.proto
|
|
237
248
|
- proto/envoy/config/core/v3/BUILD
|
|
238
249
|
- proto/envoy/config/core/v3/address.proto
|
|
239
250
|
- proto/envoy/config/core/v3/backoff.proto
|
|
@@ -268,6 +279,8 @@ files:
|
|
|
268
279
|
- proto/envoy/config/route/v3/route.proto
|
|
269
280
|
- proto/envoy/config/route/v3/route_components.proto
|
|
270
281
|
- proto/envoy/config/route/v3/scoped_route.proto
|
|
282
|
+
- proto/envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3/client_side_weighted_round_robin.proto
|
|
283
|
+
- proto/envoy/extensions/load_balancing_policies/common/v3/common.proto
|
|
271
284
|
- proto/envoy/extensions/transport_sockets/tls/v3/BUILD
|
|
272
285
|
- proto/envoy/extensions/transport_sockets/tls/v3/cert.proto
|
|
273
286
|
- proto/envoy/extensions/transport_sockets/tls/v3/common.proto
|
|
@@ -299,6 +312,7 @@ files:
|
|
|
299
312
|
- proto/envoy/type/range.proto
|
|
300
313
|
- proto/envoy/type/semantic_version.proto
|
|
301
314
|
- proto/envoy/type/token_bucket.proto
|
|
315
|
+
- proto/envoy/type/tracing/v3/custom_tag.proto
|
|
302
316
|
- proto/envoy/type/v3/BUILD
|
|
303
317
|
- proto/envoy/type/v3/hash_policy.proto
|
|
304
318
|
- proto/envoy/type/v3/http.proto
|
|
@@ -336,6 +350,8 @@ files:
|
|
|
336
350
|
- proto/xds/core/v3/resource.proto
|
|
337
351
|
- proto/xds/core/v3/resource_locator.proto
|
|
338
352
|
- proto/xds/core/v3/resource_name.proto
|
|
353
|
+
- proto/xds/data/orca/v3/orca_load_report.proto
|
|
354
|
+
- proto/xds/service/orca/v3/orca.proto
|
|
339
355
|
- proto/xds/type/matcher/v3/cel.proto
|
|
340
356
|
- proto/xds/type/matcher/v3/domain.proto
|
|
341
357
|
- proto/xds/type/matcher/v3/http_inputs.proto
|
metadata.gz.sig
CHANGED
|
Binary file
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Released under the MIT License.
|
|
4
|
-
# Copyright, 2026, by Samuel Williams.
|
|
5
|
-
|
|
6
|
-
require "google/protobuf/any_pb"
|
|
7
|
-
require "google/protobuf/duration_pb"
|
|
8
|
-
|
|
9
|
-
require "envoy/config/cluster/v3/cluster_pb"
|
|
10
|
-
require "envoy/config/core/v3/address_pb"
|
|
11
|
-
require "envoy/config/core/v3/config_source_pb"
|
|
12
|
-
require "envoy/config/core/v3/health_check_pb"
|
|
13
|
-
require "envoy/config/core/v3/protocol_pb"
|
|
14
|
-
require "envoy/config/endpoint/v3/endpoint_pb"
|
|
15
|
-
require "envoy/config/endpoint/v3/endpoint_components_pb"
|
|
16
|
-
|
|
17
|
-
module Async
|
|
18
|
-
module GRPC
|
|
19
|
-
module XDS
|
|
20
|
-
# Builds Envoy xDS resource protobufs.
|
|
21
|
-
module ResourceBuilder
|
|
22
|
-
TYPE_URL_PREFIX = "type.googleapis.com"
|
|
23
|
-
|
|
24
|
-
CLUSTER_TYPE = "#{TYPE_URL_PREFIX}/envoy.config.cluster.v3.Cluster"
|
|
25
|
-
ENDPOINT_TYPE = "#{TYPE_URL_PREFIX}/envoy.config.endpoint.v3.ClusterLoadAssignment"
|
|
26
|
-
|
|
27
|
-
# Pack a protobuf resource into a `google.protobuf.Any` message.
|
|
28
|
-
# @parameter resource [Google::Protobuf::MessageExts] The protobuf resource to pack.
|
|
29
|
-
# @returns [Google::Protobuf::Any] The packed resource.
|
|
30
|
-
def self.pack(resource)
|
|
31
|
-
Google::Protobuf::Any.new(
|
|
32
|
-
type_url: "#{TYPE_URL_PREFIX}/#{resource.class.descriptor.name}",
|
|
33
|
-
value: resource.to_proto
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Build an EDS cluster resource.
|
|
38
|
-
# @parameter name [String] The cluster name.
|
|
39
|
-
# @parameter service_name [String] The EDS service name.
|
|
40
|
-
# @parameter load_balancer_policy [Symbol] The Envoy load-balancing policy.
|
|
41
|
-
# @parameter connect_timeout [Numeric] The upstream connection timeout in seconds.
|
|
42
|
-
# @parameter protocol [Symbol] The canonical upstream protocol, either `:http1` or `:http2`.
|
|
43
|
-
# @returns [Envoy::Config::Cluster::V3::Cluster] The generated cluster resource.
|
|
44
|
-
# @raises [ArgumentError] If the upstream protocol is unsupported.
|
|
45
|
-
def self.cluster(name, service_name: name, load_balancer_policy: :round_robin, connect_timeout: 5, protocol: :http2)
|
|
46
|
-
options = {
|
|
47
|
-
name: name.to_s,
|
|
48
|
-
type: Envoy::Config::Cluster::V3::Cluster::DiscoveryType::EDS,
|
|
49
|
-
eds_cluster_config: Envoy::Config::Cluster::V3::Cluster::EdsClusterConfig.new(
|
|
50
|
-
service_name: service_name.to_s,
|
|
51
|
-
eds_config: Envoy::Config::Core::V3::ConfigSource.new(
|
|
52
|
-
ads: Envoy::Config::Core::V3::AggregatedConfigSource.new
|
|
53
|
-
)
|
|
54
|
-
),
|
|
55
|
-
connect_timeout: duration(connect_timeout),
|
|
56
|
-
lb_policy: load_balancer_policy_value(load_balancer_policy),
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
case protocol
|
|
60
|
-
when :http1
|
|
61
|
-
# Envoy uses HTTP/1 by default.
|
|
62
|
-
when :http2
|
|
63
|
-
options[:http2_protocol_options] = Envoy::Config::Core::V3::Http2ProtocolOptions.new
|
|
64
|
-
else
|
|
65
|
-
raise ArgumentError, "Unsupported upstream protocol: #{protocol.inspect}"
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
Envoy::Config::Cluster::V3::Cluster.new(**options)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Build an EDS cluster load assignment from normalized endpoint state.
|
|
72
|
-
# @parameter cluster_name [String] The cluster name.
|
|
73
|
-
# @parameter endpoints [Array(Hash)] The endpoints, each containing `:addresses` and `:healthy`.
|
|
74
|
-
# @returns [Envoy::Config::Endpoint::V3::ClusterLoadAssignment] The generated load assignment.
|
|
75
|
-
def self.cluster_load_assignment(cluster_name, endpoints)
|
|
76
|
-
Envoy::Config::Endpoint::V3::ClusterLoadAssignment.new(
|
|
77
|
-
cluster_name: cluster_name.to_s,
|
|
78
|
-
endpoints: [
|
|
79
|
-
Envoy::Config::Endpoint::V3::LocalityLbEndpoints.new(
|
|
80
|
-
lb_endpoints: endpoints.map{|endpoint| load_balancer_endpoint(endpoint)}
|
|
81
|
-
)
|
|
82
|
-
]
|
|
83
|
-
)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Build an Envoy load-balancer endpoint from normalized endpoint state.
|
|
87
|
-
# @parameter endpoint [Hash] The endpoint containing `:addresses` and `:healthy`.
|
|
88
|
-
# @returns [Envoy::Config::Endpoint::V3::LbEndpoint] The generated load-balancer endpoint.
|
|
89
|
-
# @raises [KeyError] If required endpoint state is missing.
|
|
90
|
-
# @raises [ArgumentError] If the endpoint has no addresses.
|
|
91
|
-
def self.load_balancer_endpoint(endpoint)
|
|
92
|
-
addresses, healthy = endpoint.fetch_values(:addresses, :healthy)
|
|
93
|
-
raise ArgumentError, "An endpoint requires at least one address!" if addresses.empty?
|
|
94
|
-
|
|
95
|
-
address, *additional_addresses = addresses
|
|
96
|
-
|
|
97
|
-
Envoy::Config::Endpoint::V3::LbEndpoint.new(
|
|
98
|
-
endpoint: Envoy::Config::Endpoint::V3::Endpoint.new(
|
|
99
|
-
address: build_address(address),
|
|
100
|
-
additional_addresses: additional_addresses.map do |additional_address|
|
|
101
|
-
Envoy::Config::Endpoint::V3::Endpoint::AdditionalAddress.new(
|
|
102
|
-
address: build_address(additional_address)
|
|
103
|
-
)
|
|
104
|
-
end
|
|
105
|
-
),
|
|
106
|
-
health_status: health_status_value(healthy)
|
|
107
|
-
)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Build an Envoy address from a normalized IP or Unix address.
|
|
111
|
-
# @parameter address [Hash] An IP `:address` and `:port`, or a Unix `:path`.
|
|
112
|
-
# @returns [Envoy::Config::Core::V3::Address] The generated Envoy address.
|
|
113
|
-
# @raises [KeyError] If required IP address state is missing.
|
|
114
|
-
# @private
|
|
115
|
-
def self.build_address(address)
|
|
116
|
-
if path = address[:path]
|
|
117
|
-
Envoy::Config::Core::V3::Address.new(
|
|
118
|
-
pipe: Envoy::Config::Core::V3::Pipe.new(path: path)
|
|
119
|
-
)
|
|
120
|
-
else
|
|
121
|
-
Envoy::Config::Core::V3::Address.new(
|
|
122
|
-
socket_address: Envoy::Config::Core::V3::SocketAddress.new(
|
|
123
|
-
protocol: Envoy::Config::Core::V3::SocketAddress::Protocol::TCP,
|
|
124
|
-
address: address.fetch(:address),
|
|
125
|
-
port_value: address.fetch(:port)
|
|
126
|
-
)
|
|
127
|
-
)
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
private_class_method :build_address
|
|
132
|
-
|
|
133
|
-
# Convert seconds to a protobuf duration.
|
|
134
|
-
# @parameter seconds [Numeric] The duration in seconds.
|
|
135
|
-
# @returns [Google::Protobuf::Duration] The protobuf duration.
|
|
136
|
-
def self.duration(seconds)
|
|
137
|
-
whole_seconds = seconds.to_i
|
|
138
|
-
nanos = ((seconds.to_f - whole_seconds) * 1_000_000_000).to_i
|
|
139
|
-
|
|
140
|
-
Google::Protobuf::Duration.new(seconds: whole_seconds, nanos: nanos)
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
# Convert a load-balancer policy name to its Envoy enum value.
|
|
144
|
-
# @parameter load_balancer_policy [Symbol | String | Integer] The load-balancer policy.
|
|
145
|
-
# @returns [Integer] The Envoy load-balancer policy enum value.
|
|
146
|
-
def self.load_balancer_policy_value(load_balancer_policy)
|
|
147
|
-
case load_balancer_policy
|
|
148
|
-
when :round_robin, :ROUND_ROBIN, "round_robin", "ROUND_ROBIN"
|
|
149
|
-
Envoy::Config::Cluster::V3::Cluster::LbPolicy::ROUND_ROBIN
|
|
150
|
-
when :least_request, :LEAST_REQUEST, "least_request", "LEAST_REQUEST"
|
|
151
|
-
Envoy::Config::Cluster::V3::Cluster::LbPolicy::LEAST_REQUEST
|
|
152
|
-
when :random, :RANDOM, "random", "RANDOM"
|
|
153
|
-
Envoy::Config::Cluster::V3::Cluster::LbPolicy::RANDOM
|
|
154
|
-
else
|
|
155
|
-
load_balancer_policy
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
# Convert an endpoint health status to its Envoy enum value.
|
|
160
|
-
# @parameter healthy [Boolean | Symbol | String] The normalized health status.
|
|
161
|
-
# @returns [Integer] The Envoy health-status enum value.
|
|
162
|
-
def self.health_status_value(healthy)
|
|
163
|
-
case healthy
|
|
164
|
-
when :healthy, :HEALTHY, "healthy", "HEALTHY", true
|
|
165
|
-
Envoy::Config::Core::V3::HealthStatus::HEALTHY
|
|
166
|
-
when :unhealthy, :UNHEALTHY, "unhealthy", "UNHEALTHY", false
|
|
167
|
-
Envoy::Config::Core::V3::HealthStatus::UNHEALTHY
|
|
168
|
-
when :degraded, :DEGRADED, "degraded", "DEGRADED"
|
|
169
|
-
Envoy::Config::Core::V3::HealthStatus::DEGRADED
|
|
170
|
-
else
|
|
171
|
-
Envoy::Config::Core::V3::HealthStatus::UNKNOWN
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|