Skip to content

Commit ebbb833

Browse files
kanurag94wbpcode
authored andcommitted
dynamic_modules: add bool metadata, metadata keys/namespaces, and bool attribute ABI (http) (#43537)
**Commit Message**: dynamic_modules: add bool metadata, metadata keys/namespaces, and bool attribute ABI **Additional Description**: Extends the dynamic modules ABI and SDK (Go + C++) with: - `GetMetadataBool` / `SetMetadataBool` — bool metadata getter/setter - `GetMetadataKeys` — Get all keys a metadata namespace - `GetMetadataNamespaces` — Get all metadata namespace names - `GetAttributeBool` — bool attribute getter (e.g. ConnectionMtls) **Risk Level**: Low **Testing**: Added C++ unit tests for all new ABI functions + Go integration test extensions. Manually tested with a Go dynamic module against envoy build **Docs Changes**: N/A **Release Notes**: N/A Platform Specific Features: N/A [Optional Runtime guard:] N/A [Optional Fixes #Issue]: N/A [Optional Fixes commit #PR or SHA]: N/A [Optional Deprecated:]: N/A [Optional [API Considerations](https://github.com/envoyproxy/envoy/blob/main/api/review_checklist.md):] N/A --------- Signed-off-by: Anurag Aggarwal <kanurag94@gmail.com>
1 parent f3b97c7 commit ebbb833

13 files changed

Lines changed: 1379 additions & 14 deletions

File tree

source/extensions/dynamic_modules/abi/abi.h

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1575,6 +1575,120 @@ bool envoy_dynamic_module_callback_http_get_metadata_string(
15751575
envoy_dynamic_module_type_module_buffer ns, envoy_dynamic_module_type_module_buffer key,
15761576
envoy_dynamic_module_type_envoy_buffer* result);
15771577

1578+
/**
1579+
* envoy_dynamic_module_callback_http_set_dynamic_metadata_bool is called by the module to set
1580+
* the bool value of the dynamic metadata with the given namespace and key. If the metadata is
1581+
* existing, it will be overwritten.
1582+
*
1583+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1584+
* corresponding HTTP filter.
1585+
* @param ns is the namespace of the dynamic metadata.
1586+
* @param key is the key of the dynamic metadata.
1587+
* @param value is the bool value of the dynamic metadata to be set.
1588+
*/
1589+
void envoy_dynamic_module_callback_http_set_dynamic_metadata_bool(
1590+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1591+
envoy_dynamic_module_type_module_buffer ns, envoy_dynamic_module_type_module_buffer key,
1592+
bool value);
1593+
1594+
/**
1595+
* envoy_dynamic_module_callback_http_get_metadata_bool is called by the module to get
1596+
* the bool value of the dynamic metadata with the given namespace and key. If the metadata is not
1597+
* accessible, the namespace does not exist, the key does not exist or the value is not a bool,
1598+
* this returns false.
1599+
*
1600+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1601+
* corresponding HTTP filter.
1602+
* @param metadata_source is the source of the metadata.
1603+
* @param ns is the namespace of the dynamic metadata.
1604+
* @param key is the key of the dynamic metadata.
1605+
* @param result is the pointer to the variable where the bool value of the dynamic metadata will
1606+
* be stored.
1607+
* @return true if the operation is successful, false otherwise.
1608+
*/
1609+
bool envoy_dynamic_module_callback_http_get_metadata_bool(
1610+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1611+
envoy_dynamic_module_type_metadata_source metadata_source,
1612+
envoy_dynamic_module_type_module_buffer ns, envoy_dynamic_module_type_module_buffer key,
1613+
bool* result);
1614+
1615+
/**
1616+
* envoy_dynamic_module_callback_http_get_metadata_keys_count is called by the module to get the
1617+
* number of keys in the metadata namespace. If the metadata is not accessible or the namespace
1618+
* does not exist, this returns 0.
1619+
*
1620+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1621+
* corresponding HTTP filter.
1622+
* @param metadata_source is the source of the metadata.
1623+
* @param ns is the namespace of the dynamic metadata.
1624+
* @return the number of keys in the metadata namespace.
1625+
*/
1626+
size_t envoy_dynamic_module_callback_http_get_metadata_keys_count(
1627+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1628+
envoy_dynamic_module_type_metadata_source metadata_source,
1629+
envoy_dynamic_module_type_module_buffer ns);
1630+
1631+
/**
1632+
* envoy_dynamic_module_callback_http_get_metadata_keys is called by the module to get all keys
1633+
* in the metadata namespace. The keys are returned as an array of
1634+
* envoy_dynamic_module_type_envoy_buffer.
1635+
*
1636+
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
1637+
* to store all the keys. The module can use
1638+
* envoy_dynamic_module_callback_http_get_metadata_keys_count to get the number of
1639+
* keys before calling this function.
1640+
*
1641+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1642+
* corresponding HTTP filter.
1643+
* @param metadata_source is the source of the metadata.
1644+
* @param ns is the namespace of the dynamic metadata.
1645+
* @param result_buffer_vector is the pointer to the array of envoy_dynamic_module_type_envoy_buffer
1646+
* where the key strings will be stored. The lifetime of the buffer is guaranteed until the
1647+
* end of the current event hook unless the setter callback is called.
1648+
* @return true if the operation is successful, false otherwise.
1649+
*/
1650+
bool envoy_dynamic_module_callback_http_get_metadata_keys(
1651+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1652+
envoy_dynamic_module_type_metadata_source metadata_source,
1653+
envoy_dynamic_module_type_module_buffer ns,
1654+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
1655+
1656+
/**
1657+
* envoy_dynamic_module_callback_http_get_metadata_namespaces_count is called by the module to get
1658+
* the number of namespaces in the metadata. If the metadata is not accessible, this returns 0.
1659+
*
1660+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1661+
* corresponding HTTP filter.
1662+
* @param metadata_source is the source of the metadata.
1663+
* @return the number of namespaces in the metadata.
1664+
*/
1665+
size_t envoy_dynamic_module_callback_http_get_metadata_namespaces_count(
1666+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1667+
envoy_dynamic_module_type_metadata_source metadata_source);
1668+
1669+
/**
1670+
* envoy_dynamic_module_callback_http_get_metadata_namespaces is called by the module to get all
1671+
* namespace names in the metadata. The namespaces are returned as an array of
1672+
* envoy_dynamic_module_type_envoy_buffer.
1673+
*
1674+
* PRECONDITION: The module must ensure that the result_buffer_vector is valid and has enough length
1675+
* to store all the namespaces. The module can use
1676+
* envoy_dynamic_module_callback_http_get_metadata_namespaces_count to get the number of
1677+
* namespaces before calling this function.
1678+
*
1679+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1680+
* corresponding HTTP filter.
1681+
* @param metadata_source is the source of the metadata.
1682+
* @param result_buffer_vector is the pointer to the array of envoy_dynamic_module_type_envoy_buffer
1683+
* where the namespace strings will be stored. The lifetime of the buffer is guaranteed until the
1684+
* end of the current event hook unless the setter callback is called.
1685+
* @return true if the operation is successful, false otherwise.
1686+
*/
1687+
bool envoy_dynamic_module_callback_http_get_metadata_namespaces(
1688+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1689+
envoy_dynamic_module_type_metadata_source metadata_source,
1690+
envoy_dynamic_module_type_envoy_buffer* result_buffer_vector);
1691+
15781692
// -------------------------- Filter State Callbacks ---------------------------
15791693

15801694
/**
@@ -1773,6 +1887,24 @@ bool envoy_dynamic_module_callback_http_filter_get_attribute_int(
17731887
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
17741888
envoy_dynamic_module_type_attribute_id attribute_id, uint64_t* result);
17751889

1890+
/**
1891+
* envoy_dynamic_module_callback_http_filter_get_attribute_bool is called by the module to get
1892+
* a boolean attribute value. If the attribute is not accessible or the
1893+
* value is not a boolean, this returns false.
1894+
*
1895+
* @param filter_envoy_ptr is the pointer to the DynamicModuleHttpFilter object of the
1896+
* corresponding HTTP filter.
1897+
* @param attribute_id is the ID of the attribute.
1898+
* @param result is the pointer to the variable where the bool value of the attribute will be
1899+
* stored.
1900+
* @return true if the operation is successful, false otherwise.
1901+
*
1902+
* Note: currently, not all attributes are implemented.
1903+
*/
1904+
bool envoy_dynamic_module_callback_http_filter_get_attribute_bool(
1905+
envoy_dynamic_module_type_http_filter_envoy_ptr filter_envoy_ptr,
1906+
envoy_dynamic_module_type_attribute_id attribute_id, bool* result);
1907+
17761908
/**
17771909
* envoy_dynamic_module_callback_http_filter_http_callout is called by the module to initiate
17781910
* an HTTP callout. The callout is initiated by the HTTP filter and the response is received in

source/extensions/dynamic_modules/sdk/cpp/sdk.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <cassert>
44
#include <cstddef>
55
#include <memory>
6+
#include <string>
7+
#include <vector>
68

79
#include "absl/container/flat_hash_map.h"
810
#include "absl/types/optional.h"
@@ -378,6 +380,27 @@ class HttpFilterHandle {
378380
*/
379381
virtual absl::optional<double> getMetadataNumber(absl::string_view ns, absl::string_view key) = 0;
380382

383+
/**
384+
* Retrieves a bool metadata value by namespace and key.
385+
* @param ns The metadata namespace.
386+
* @param key The metadata key.
387+
* @return The bool value if found, otherwise nullopt.
388+
*/
389+
virtual absl::optional<bool> getMetadataBool(absl::string_view ns, absl::string_view key) = 0;
390+
391+
/**
392+
* Retrieves all keys in a metadata namespace.
393+
* @param ns The metadata namespace.
394+
* @return Vector of key strings.
395+
*/
396+
virtual std::vector<absl::string_view> getMetadataKeys(absl::string_view ns) = 0;
397+
398+
/**
399+
* Retrieves all namespace names in the metadata.
400+
* @return Vector of namespace name strings.
401+
*/
402+
virtual std::vector<absl::string_view> getMetadataNamespaces() = 0;
403+
381404
/**
382405
* Sets a string metadata value.
383406
* @param ns The metadata namespace.
@@ -395,6 +418,19 @@ class HttpFilterHandle {
395418
*/
396419
virtual void setMetadata(absl::string_view ns, absl::string_view key, double value) = 0;
397420

421+
/**
422+
* Sets a bool metadata value.
423+
* @param ns The metadata namespace.
424+
* @param key The metadata key.
425+
* @param value The bool value to set.
426+
*/
427+
virtual void setMetadata(absl::string_view ns, absl::string_view key, bool value) = 0;
428+
429+
// Prevent const char* from implicitly converting to bool instead of string_view.
430+
void setMetadata(absl::string_view ns, absl::string_view key, const char* value) {
431+
setMetadata(ns, key, absl::string_view(value));
432+
}
433+
398434
/**
399435
* Retrieves the serialized filter state value of the stream.
400436
* @param key The filter state key.
@@ -423,6 +459,13 @@ class HttpFilterHandle {
423459
*/
424460
virtual absl::optional<uint64_t> getAttributeNumber(AttributeID id) = 0;
425461

462+
/**
463+
* Retrieves a boolean attribute value.
464+
* @param id The attribute ID.
465+
* @return The bool value if found, otherwise nullopt.
466+
*/
467+
virtual absl::optional<bool> getAttributeBool(AttributeID id) = 0;
468+
426469
/**
427470
* Sends a local response with status code, body, and detail.
428471
* @param status The HTTP status code.

source/extensions/dynamic_modules/sdk/cpp/sdk_internal.cc

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,61 @@ class HttpFilterHandleImpl : public HttpFilterHandle {
225225
return value;
226226
}
227227

228+
absl::optional<bool> getMetadataBool(absl::string_view ns, absl::string_view key) override {
229+
bool value = false;
230+
const bool ret = envoy_dynamic_module_callback_http_get_metadata_bool(
231+
host_plugin_ptr_, envoy_dynamic_module_type_metadata_source_Dynamic,
232+
envoy_dynamic_module_type_module_buffer{ns.data(), ns.size()},
233+
envoy_dynamic_module_type_module_buffer{key.data(), key.size()}, &value);
234+
235+
if (!ret) {
236+
return {};
237+
}
238+
return value;
239+
}
240+
241+
std::vector<absl::string_view> getMetadataKeys(absl::string_view ns) override {
242+
size_t count = envoy_dynamic_module_callback_http_get_metadata_keys_count(
243+
host_plugin_ptr_, envoy_dynamic_module_type_metadata_source_Dynamic,
244+
envoy_dynamic_module_type_module_buffer{ns.data(), ns.size()});
245+
if (count == 0) {
246+
return {};
247+
}
248+
std::vector<envoy_dynamic_module_type_envoy_buffer> buffers(count);
249+
const bool ret = envoy_dynamic_module_callback_http_get_metadata_keys(
250+
host_plugin_ptr_, envoy_dynamic_module_type_metadata_source_Dynamic,
251+
envoy_dynamic_module_type_module_buffer{ns.data(), ns.size()}, buffers.data());
252+
if (!ret) {
253+
return {};
254+
}
255+
std::vector<absl::string_view> keys;
256+
keys.reserve(count);
257+
for (size_t i = 0; i < count; i++) {
258+
keys.emplace_back(buffers[i].ptr, buffers[i].length);
259+
}
260+
return keys;
261+
}
262+
263+
std::vector<absl::string_view> getMetadataNamespaces() override {
264+
size_t count = envoy_dynamic_module_callback_http_get_metadata_namespaces_count(
265+
host_plugin_ptr_, envoy_dynamic_module_type_metadata_source_Dynamic);
266+
if (count == 0) {
267+
return {};
268+
}
269+
std::vector<envoy_dynamic_module_type_envoy_buffer> buffers(count);
270+
const bool ret = envoy_dynamic_module_callback_http_get_metadata_namespaces(
271+
host_plugin_ptr_, envoy_dynamic_module_type_metadata_source_Dynamic, buffers.data());
272+
if (!ret) {
273+
return {};
274+
}
275+
std::vector<absl::string_view> namespaces;
276+
namespaces.reserve(count);
277+
for (size_t i = 0; i < count; i++) {
278+
namespaces.emplace_back(buffers[i].ptr, buffers[i].length);
279+
}
280+
return namespaces;
281+
}
282+
228283
void setMetadata(absl::string_view ns, absl::string_view key, absl::string_view value) override {
229284
envoy_dynamic_module_callback_http_set_dynamic_metadata_string(
230285
host_plugin_ptr_, envoy_dynamic_module_type_module_buffer{ns.data(), ns.size()},
@@ -238,6 +293,12 @@ class HttpFilterHandleImpl : public HttpFilterHandle {
238293
envoy_dynamic_module_type_module_buffer{key.data(), key.size()}, value);
239294
}
240295

296+
void setMetadata(absl::string_view ns, absl::string_view key, bool value) override {
297+
envoy_dynamic_module_callback_http_set_dynamic_metadata_bool(
298+
host_plugin_ptr_, envoy_dynamic_module_type_module_buffer{ns.data(), ns.size()},
299+
envoy_dynamic_module_type_module_buffer{key.data(), key.size()}, value);
300+
}
301+
241302
absl::optional<absl::string_view> getFilterState(absl::string_view key) override {
242303
BufferView value{nullptr, 0};
243304

@@ -281,6 +342,17 @@ class HttpFilterHandleImpl : public HttpFilterHandle {
281342
return value;
282343
}
283344

345+
absl::optional<bool> getAttributeBool(AttributeID id) override {
346+
bool value = false;
347+
const bool ret = envoy_dynamic_module_callback_http_filter_get_attribute_bool(
348+
host_plugin_ptr_, static_cast<envoy_dynamic_module_type_attribute_id>(id), &value);
349+
350+
if (!ret) {
351+
return {};
352+
}
353+
return value;
354+
}
355+
284356
void sendLocalResponse(uint32_t status, absl::Span<const HeaderView> headers,
285357
absl::string_view body, absl::string_view detail) override {
286358
envoy_dynamic_module_callback_http_send_response(

0 commit comments

Comments
 (0)