envoy-control-plane
for RustThis package exposes the Envoy xDS protos and gRPC services via prost.
It also enables reading JSON and YAML bootstrap files into prost-generated structs, e.g. if you have a bootstrap.yaml
containing:
admin: address: socketAddress: address: "127.0.0.1" portValue: 9901 node: id: envoy-test-1 cluster: envoy-test-cluster-1 staticResources: listeners: - name: server-1 address: socketAddress: address: 127.0.0.1 portValue: 9000 filterChains: - filters: - name: envoy.filters.network.httpconnectionmanager typedConfig: "@type": type.googleapis.com/envoy.extensions.filters.network.httpconnectionmanager.v3.HttpConnectionManager statPrefix: ingresshttp httpFilters: - name: envoy.filters.http.router routeConfig: name: localroute virtualHosts: - name: localservice domains: ["*"] routes: - match: prefix: "/" route: cluster: local-srv transportSocket: name: envoy.transportsockets.tls typedConfig: '@type': type.googleapis.com/envoy.extensions.transportsockets.tls.v3.DownstreamTlsContext requireClientCertificate: value: true commonTlsContext: tlsParams: tlsMinimumProtocolVersion: TLSv13 tlsMaximumProtocolVersion: TLSv13 validationContext: trustedCa: filename: ./certs/ca.crt matchTypedSubjectAltNames: - sanType: DNS matcher: exact: client.test tlsCertificates: - certificateChain: filename: ./certs/server.test.ecdsa-p256.crt privateKey: filename: ./certs/server.test.ecdsa-p256.key clusters: - name: local-srv type: STATIC lbPolicy: ROUNDROBIN loadAssignment: clusterName: local-srv endpoints: - lbEndpoints: - endpoint: address: socketAddress: address: "127.0.0.1" portValue: 9110 ```
You can read that Bootstrap config in with:
```rust use envoycontrolplane::envoy::config::bootstrap::v3::Bootstrap;
let configcontents = readall(&args.configpath).await?; let configext = args.configpath.extension().unwrapordefault(); let bootstrap: Bootstrap = if configext == "yaml" || configext == "yml" { eprintln!("WARNING: YAML support is incomplete (e.g. durations don't work)"); serdeyaml::fromstr(&configcontents)? } else { serdejson::fromstr(&config_contents)? }; ```
Envoy uses a lot of protobuf Any
values for polymorphism. As you can see above we read them off disk just fine, but there is an additional hoop to jump through in order to actually access a typed instance:
```rust let downstreamtlscontexttypeurl = DownstreamTlsContext::default().type_url();
// this works for the bootstrap config above, but real code wouldn't hardcode pulling
// the value out in such a fragile way.
let bootstraptlsconfig = bootstrap
.staticresources
.asref()
.unwrap()
.listeners[0]
.filterchains[0]
.transportsocket
.asref()
.unwrap()
.configtype
.asref()
.unwrap();
// there are not other ConfigType
enum variants, so this let works fine.
let ConfigType::TypedConfig(tlsany) = bootstraptlsconfig;
// because the TypedConfig
is Any
, we need to check the typeurl
if &tlsany.typeurl == downstreamtlscontexttypeurl {
let ctx = DownstreamTlsContext::decode(&*tlsany.value).unwrap();
// store or do something with the DownstreamTlsContext
instance
} else {
panic!("unsupported typed config: {}", &tlsany.typeurl);
}
```
lbPolicy
and not lb_policy
).pbjson
to correctly read in Any
values from JSON/YAML.The code in this package is available under the Apache 2.0 license, as found in the LICENSE file. Envoy itself (and its API protos) are also licensed under Apache 2.0.