proxy-wasm-rust-sdk icon indicating copy to clipboard operation
proxy-wasm-rust-sdk copied to clipboard

Emit Dynamic Metadata

Open Gsantomaggio opened this issue 4 years ago • 9 comments

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.

Gsantomaggio avatar Feb 17 '21 20:02 Gsantomaggio

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"));

PiotrSikora avatar Feb 17 '21 21:02 PiotrSikora

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

Gsantomaggio avatar Feb 17 '21 21:02 Gsantomaggio

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

Gsantomaggio avatar Feb 18 '21 07:02 Gsantomaggio

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?

yuval-k avatar Feb 19 '21 15:02 yuval-k

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

Gsantomaggio avatar Feb 20 '21 16:02 Gsantomaggio

@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!

PiotrSikora avatar Feb 23 '21 09:02 PiotrSikora

Thanks @PiotrSikora . here the issue https://github.com/envoyproxy/envoy/issues/15148

Gsantomaggio avatar Feb 23 '21 09:02 Gsantomaggio

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?

cetanu avatar Mar 20 '23 13:03 cetanu

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

cetanu avatar Oct 17 '23 01:10 cetanu