diff --git a/.gitignore b/.gitignore index c64ec96..c72aa20 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .vscode/ envoy-rate-limit-header/target/ -mock-backend/node_modules/ \ No newline at end of file +mock-backend/node_modules/ +header-to-metadata/add-header-filter/target/ +header-to-metadata/metadata-filter/target/ \ No newline at end of file diff --git a/header-to-metadata/add-header-filter/Cargo.lock b/header-to-metadata/add-header-filter/Cargo.lock new file mode 100644 index 0000000..3f9e701 --- /dev/null +++ b/header-to-metadata/add-header-filter/Cargo.lock @@ -0,0 +1,151 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "add-header-filter" +version = "0.1.0" +dependencies = [ + "log", + "proxy-wasm", + "wasm-bindgen", +] + +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + +[[package]] +name = "bumpalo" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proxy-wasm" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5612e16bf2c7e7f824dde8c2f9735600adffcb08ce05e66d0a7db37786a6ca6d" +dependencies = [ + "hashbrown", + "log", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wasm-bindgen" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" diff --git a/header-to-metadata/add-header-filter/Cargo.toml b/header-to-metadata/add-header-filter/Cargo.toml new file mode 100644 index 0000000..b531bce --- /dev/null +++ b/header-to-metadata/add-header-filter/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "add-header-filter" +version = "0.1.0" +authors = ["Lahiru Udayanga "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +proxy-wasm = "0.1.3" +log = "0.4.14" +wasm-bindgen = "0.2.74" diff --git a/header-to-metadata/add-header-filter/Makefile b/header-to-metadata/add-header-filter/Makefile new file mode 100644 index 0000000..0a32d57 --- /dev/null +++ b/header-to-metadata/add-header-filter/Makefile @@ -0,0 +1,9 @@ +build: add_header_filter.wasm + +add_header_filter.wasm: + cargo build --target wasm32-unknown-unknown --release + cp target/wasm32-unknown-unknown/release/add_header_filter.wasm ../build/add_header_filter.wasm + +.PHONY: clean +clean: + rm ../build/add_header_filter.wasm || true \ No newline at end of file diff --git a/header-to-metadata/add-header-filter/src/lib.rs b/header-to-metadata/add-header-filter/src/lib.rs new file mode 100644 index 0000000..13060ae --- /dev/null +++ b/header-to-metadata/add-header-filter/src/lib.rs @@ -0,0 +1,43 @@ +use log::info; +use proxy_wasm::traits::*; +use proxy_wasm::types::*; + +#[no_mangle] +pub fn _start() { + proxy_wasm::set_log_level(LogLevel::Info); + proxy_wasm::set_root_context(|_| -> Box { Box::new(HttpHeadersRoot) }); +} + +struct HttpHeadersRoot; + +impl Context for HttpHeadersRoot {} + +impl RootContext for HttpHeadersRoot { + fn get_type(&self) -> Option { + Some(ContextType::HttpContext) + } + + fn create_http_context(&self, context_id: u32) -> Option> { + Some(Box::new(HttpHeaders { context_id })) + } +} + +struct HttpHeaders { + context_id: u32, +} + +impl Context for HttpHeaders {} + +impl HttpContext for HttpHeaders { + fn on_http_request_headers(&mut self, _: usize) -> Action { + // Add metadata headers. These metadata headers will be added as dynamic metadata from the header to metadata filter. + self.add_http_request_header("x-3scale-service-key", "123456789"); + self.add_http_request_header("x-3scale-application-key", "987654321"); + info!("3scale metadata headers added from the request path"); + Action::Continue + } + + fn on_log(&mut self) { + info!("#{} completed.", self.context_id); + } +} diff --git a/header-to-metadata/build/add_header_filter.wasm b/header-to-metadata/build/add_header_filter.wasm new file mode 100755 index 0000000..a26b67d Binary files /dev/null and b/header-to-metadata/build/add_header_filter.wasm differ diff --git a/header-to-metadata/build/metadata_filter.wasm b/header-to-metadata/build/metadata_filter.wasm new file mode 100755 index 0000000..d9cba47 Binary files /dev/null and b/header-to-metadata/build/metadata_filter.wasm differ diff --git a/header-to-metadata/docker-compose.yaml b/header-to-metadata/docker-compose.yaml new file mode 100644 index 0000000..d140945 --- /dev/null +++ b/header-to-metadata/docker-compose.yaml @@ -0,0 +1,23 @@ +version: '3.7' +services: + envoy: + build: + context: ./ + dockerfile: ./resources/Dockerfile + depends_on: + - backend_service + networks: + - envoymesh + ports: + - "9095:9095" + - "9000:9000" + + backend_service: + build: + context: ../mock-backend + dockerfile: Dockerfile + networks: + - envoymesh + +networks: + envoymesh: {} \ No newline at end of file diff --git a/header-to-metadata/metadata-filter/Cargo.lock b/header-to-metadata/metadata-filter/Cargo.lock new file mode 100644 index 0000000..23073fb --- /dev/null +++ b/header-to-metadata/metadata-filter/Cargo.lock @@ -0,0 +1,151 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + +[[package]] +name = "bumpalo" +version = "3.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "metadata-filter" +version = "0.1.0" +dependencies = [ + "log", + "proxy-wasm", + "wasm-bindgen", +] + +[[package]] +name = "proc-macro2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "proxy-wasm" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5612e16bf2c7e7f824dde8c2f9735600adffcb08ce05e66d0a7db37786a6ca6d" +dependencies = [ + "hashbrown", + "log", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wasm-bindgen" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" diff --git a/header-to-metadata/metadata-filter/Cargo.toml b/header-to-metadata/metadata-filter/Cargo.toml new file mode 100644 index 0000000..e492046 --- /dev/null +++ b/header-to-metadata/metadata-filter/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "metadata-filter" +version = "0.1.0" +authors = ["Lahiru Udayanga "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +path = "src/lib.rs" +crate-type = ["cdylib"] + +[dependencies] +proxy-wasm = "0.1.3" +log = "0.4.14" +wasm-bindgen = "0.2.74" \ No newline at end of file diff --git a/header-to-metadata/metadata-filter/Makefile b/header-to-metadata/metadata-filter/Makefile new file mode 100644 index 0000000..7902b9a --- /dev/null +++ b/header-to-metadata/metadata-filter/Makefile @@ -0,0 +1,9 @@ +build: metadata_filter.wasm + +metadata_filter.wasm: + cargo build --target wasm32-unknown-unknown --release + cp target/wasm32-unknown-unknown/release/metadata_filter.wasm ../build/metadata_filter.wasm + +.PHONY: clean +clean: + rm ../build/metadata_filter.wasm || true \ No newline at end of file diff --git a/header-to-metadata/metadata-filter/src/lib.rs b/header-to-metadata/metadata-filter/src/lib.rs new file mode 100644 index 0000000..5b98ba3 --- /dev/null +++ b/header-to-metadata/metadata-filter/src/lib.rs @@ -0,0 +1,65 @@ +use log::info; +use proxy_wasm::traits::*; +use proxy_wasm::types::*; +use std::str; + +#[no_mangle] +pub fn _start() { + proxy_wasm::set_log_level(LogLevel::Info); + proxy_wasm::set_root_context(|_| -> Box { Box::new(MetadataRoot) }); +} + +struct MetadataRoot; + +impl Context for MetadataRoot {} + +impl RootContext for MetadataRoot { + fn get_type(&self) -> Option { + Some(ContextType::HttpContext) + } + + fn create_http_context(&self, context_id: u32) -> Option> { + Some(Box::new(MetadataFilter { context_id })) + } +} + +struct MetadataFilter { + context_id: u32, +} + +impl Context for MetadataFilter {} + +impl HttpContext for MetadataFilter { + fn on_http_request_headers(&mut self, _: usize) -> Action { + for (name, value) in &self.get_http_request_headers() { + info!("#{} -> {}: {}", self.context_id, name, value); + } + info!("Metadata filter intercepted the HTTP request"); + let service_key_utf8 = self + .get_property(vec!["metadata", "filter_metadata", "3scale", "service_key"]) + .unwrap(); + let service_key = match str::from_utf8(&service_key_utf8) { + Ok(sk) => sk, + Err(e) => panic!("Error : {}", e), + }; + let application_key_utf8 = self + .get_property(vec![ + "metadata", + "filter_metadata", + "3scale", + "application_key", + ]) + .unwrap(); + let application_key = match str::from_utf8(&application_key_utf8) { + Ok(ak) => ak, + Err(e) => panic!("Error: {}", e), + }; + info!("service key from dynamic metadata: {}", service_key); + info!("application key from dynamic metadata: {}", application_key); + Action::Continue + } + + fn on_log(&mut self) { + info!("#{} completed.", self.context_id); + } +} diff --git a/header-to-metadata/resources/Dockerfile b/header-to-metadata/resources/Dockerfile new file mode 100644 index 0000000..8193743 --- /dev/null +++ b/header-to-metadata/resources/Dockerfile @@ -0,0 +1,11 @@ +FROM envoyproxy/envoy:v1.18.3 + +# Copy envoy.yaml & wasm module +COPY ./resources/envoy.yaml /etc/envoy/envoy.yaml +COPY ./build/add_header_filter.wasm /usr/local/bin/add_header_filter.wasm +COPY ./build/metadata_filter.wasm /usr/local/bin/metadata_filter.wasm + +# Setup permission +RUN chmod go+r /etc/envoy/envoy.yaml /usr/local/bin/add_header_filter.wasm /usr/local/bin/metadata_filter.wasm + +CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml \ No newline at end of file diff --git a/header-to-metadata/resources/envoy.yaml b/header-to-metadata/resources/envoy.yaml new file mode 100644 index 0000000..a9e413d --- /dev/null +++ b/header-to-metadata/resources/envoy.yaml @@ -0,0 +1,113 @@ +admin: + access_log_path: /dev/null + address: + socket_address: + address: 0.0.0.0 + port_value: 9000 +static_resources: + listeners: + - address: + socket_address: + address: 0.0.0.0 + port_value: 9095 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + codec_type: auto + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: local_service + domains: + - "*" + routes: + - match: + prefix: "/foo" + route: + cluster: backend_service + - match: + prefix: "/bar" + route: + cluster: backend_service + - match: + prefix: "/baz" + route: + cluster: backend_service + http_filters: + - name: envoy.filters.http.wasm + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + name: "htm" + root_id: "htm_root" + vm_config: + runtime: "envoy.wasm.runtime.v8" + vm_id: "htm_vm" + code: + local: + filename: "/usr/local/bin/add_header_filter.wasm" + configuration: {} + allow_precompiled: true + - name: envoy.filters.http.header_to_metadata + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.header_to_metadata.v3.Config + request_rules: + - header: x-3scale-service-key + on_header_present: + metadata_namespace: 3scale + key: service_key + type: STRING + on_header_missing: + metadata_namespace: 3scale + key: service_key + value: '123456' + type: STRING + remove: false + - header: x-3scale-application-key + on_header_present: + metadata_namespace: 3scale + key: application_key + type: STRING + on_header_missing: + metadata_namespace: 3scale + key: application_key + value: '123456' + type: STRING + remove: false + - name: envoy.filters.http.wasm + typed_config: + "@type": type.googleapis.com/udpa.type.v1.TypedStruct + type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm + value: + config: + name: "htm" + root_id: "htm_root" + vm_config: + runtime: "envoy.wasm.runtime.v8" + vm_id: "htm_vm" + code: + local: + filename: "/usr/local/bin/metadata_filter.wasm" + configuration: {} + allow_precompiled: true + - name: envoy.filters.http.router + typed_config: {} + clusters: + - name: backend_service + connect_timeout: 0.25s + type: strict_dns + lb_policy: round_robin + load_assignment: + cluster_name: backend_service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: backend_service + port_value: 8000 \ No newline at end of file