proxy-wasm-rust-sdk
proxy-wasm-rust-sdk copied to clipboard
Emit Dynamic Metadata
Hi all,
I'd need to integrate my network filter with RBAC.
I saw that standard filters use setDynamicMetadata
to emit the metadata.
I am looking for something similar in the SDK, is that possible?
Thank you for time.
It's not clear to me what kind of integration do you mean, but you can set filter metadata using set_property
, e.g.
self.set_property(vec!["metadata", "filter_metadata", "envoy.filters.network.rbac", "something"], Some("value"));
Thank you @PiotrSikora
I'd need to implement something very similar to https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/mysql_proxy_filter#dynamic-metadata
Hi @PiotrSikora I changed the issue name hope it is more clear. What I am looking for is how to emit dynamic metadata so in this way, I can integrate my filter with RBAC as MySQL filter does.
I think that your comment is about setting the proxy properties.
For the documentation:
setDynamicMetadata routine in the StreamInfo interface on a Connection
I am wondering if it is possible with the Rust SDK.
Thank you for your time
hi @PiotrSikora , from looking at the code, I can see how to fetch dynamic metadata with getProperty, but it's hard to see how Context::setProperty sets dynamic metadata.
If I'm understanding the code correctly, setProperty can only set filterState
and things that were registered using declareProperty
?
I changed the envoy proxy wasm context.cc just for test
In this way (Thanks to @yuval-k to pointed me on it):
WasmResult Context::setProperty(absl::string_view path, absl::string_view value) {
auto* stream_info = getRequestStreamInfo();
if (!stream_info) {
return WasmResult::NotFound;
}
// ENVOY_LOG(debug, "***** setProperty wasm path:{} value:{}", path, value);
ProtobufWkt::Struct metadata_val;
auto& fields_a = *metadata_val.mutable_fields();
std::string v1;
absl::StrAppend(&v1, value);
fields_a[v1].set_bool_value(true);
std::string key3;
absl::StrAppend(&key3, path);
stream_info->setDynamicMetadata(key3, metadata_val);
Rust code:
self.set_property(vec!["my.filters.network.network"],
Some("myitem".as_ref()));
And actually the filter works:
[2021-02-20 16:45:17.749][7215663][debug][rbac] [source/extensions/filters/network/rbac/rbac_filter.cc:45] checking connection: requestedServerName: , sourceIP: 127.0.0.1:54608, directRemoteIP: 127.0.0.1:54608,remoteIP: 127.0.0.1:54608, localAddress: 127.0.0.1:5673, ssl: none,
dynamicMetadata: filter_metadata {
key: "my.filters.network.network"
value {
fields {
key: "myitem"
value {
bool_value: true
}
}
}
}
and also the RBAC works:
[2021-02-19 20:02:20.480][6826232][debug][rbac] [source/extensions/filters/network/rbac/rbac_filter.cc:125]
enforced denied, matched policy myitem-policy
envoy conf:
filter_chains:
- filters:
- name: envoy.filters.network.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
config:
configuration: {"@type":"type.googleapis.com/google.protobuf.StringValue",
"value":""}
name: "my.filters.network.network"
root_id: "my.filters.network.network"
vm_config:
vm_id: "my.filters.network.network"
runtime: envoy.wasm.runtime.v8
code: {"local":{"filename":"wasm32-unknown-unknown/release/my_network_filter.wasm"}}
allow_precompiled: true
- name: envoy.filters.network.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
stat_prefix: rbac
rules:
action: DENY
policies:
"myqueue-policy":
permissions:
- metadata:
filter: my.filters.network.network
path:
- key: myitem
value:
bool_match: true
setDynamicMetadata
seems to be a missing feature on envoy mainstream. I was thinking of to open an issue on envoy
@yuval-k you're right, I was under impression that FilterState
and DynamicMetadata
were merged together, but it doesn't look that's the case yet (see: https://github.com/envoyproxy/envoy/issues/4929).
@Gsantomaggio yeah, it looks like it's missing in Envoy. Feel free to open an issue and/or send a PR there. Thanks!
Thanks @PiotrSikora . here the issue https://github.com/envoyproxy/envoy/issues/15148
I rigged up a basic example to try to get this working, using the example from @PiotrSikora https://github.com/cetanu/envoy_rust_wasm_sandbox/blob/master/src/lib.rs
However... So far I am unable to get the property to be logged... Am I doing something horribly wrong in this example?
For anyone stumbling onto this thread, using shared data seems to work...
https://github.com/cetanu/envoy_rust_wasm_sandbox/blob/master/src/lib.rs#L37