Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit Dynamic Metadata #81

Open
Gsantomaggio opened this issue Feb 17, 2021 · 12 comments
Open

Emit Dynamic Metadata #81

Gsantomaggio opened this issue Feb 17, 2021 · 12 comments

Comments

@Gsantomaggio
Copy link
Contributor

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.

@PiotrSikora
Copy link
Member

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

@Gsantomaggio
Copy link
Contributor Author

@Gsantomaggio Gsantomaggio changed the title RBAC integration Emit Dynamic Metadata Feb 18, 2021
@Gsantomaggio
Copy link
Contributor Author

Gsantomaggio commented Feb 18, 2021

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

@yuval-k
Copy link
Contributor

yuval-k commented Feb 19, 2021

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?

@Gsantomaggio
Copy link
Contributor Author

Gsantomaggio commented Feb 20, 2021

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

@PiotrSikora
Copy link
Member

@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: envoyproxy/envoy#4929).

@Gsantomaggio yeah, it looks like it's missing in Envoy. Feel free to open an issue and/or send a PR there. Thanks!

@Gsantomaggio
Copy link
Contributor Author

Thanks @PiotrSikora .
here the issue envoyproxy/envoy#15148

@cetanu
Copy link

cetanu commented Mar 20, 2023

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
Copy link

cetanu commented Oct 17, 2023

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

@leandrocurioso
Copy link

@cetanu one question, the shared data is usable only in the filter chain or is shared between all incoming requests?

I need a way to each http context (during filter chain) have their own temporary key pair storage and after the response is automatically cleared.

@PiotrSikora
Copy link
Member

I need a way to each http context (during filter chain) have their own temporary key pair storage and after the response is automatically cleared.

It sounds like you want to store this key as field in HttpContext (see: examples/http_headers).

@leandrocurioso
Copy link

leandrocurioso commented Jan 20, 2025

automatically cleared.

@PiotrSikora I need to extract a json body field on_http_request_body and add a custom header but the VM panics!

I noticed that if I add a header inside on_http_request_headers it works but not for on_http_request_body.

I also noticed that on_http_request_headers is executed first than on_http_request_body.

How can I have a http request context that data could be available only inside the filter chain and by the end of the response is automatically cleared? (Premise! The header must be added after the body parsing)

Maybe a way to work with dynamic metadata? I was looking into this but not sure if it will work:
https://www.envoyproxy.io/docs/envoy/v1.31.5/configuration/advanced/well_known_dynamic_metadata#shared-dynamic-metadata

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants