Skip to content

Commit

Permalink
examples/docs: Cleanups for Lua cluster specifier (envoyproxy#32120)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Northey <[email protected]>
  • Loading branch information
phlax authored Jan 31, 2024
1 parent deab45f commit 0edcdf8
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 75 deletions.
88 changes: 44 additions & 44 deletions docs/root/configuration/http/cluster_specifier/lua.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,68 @@ Lua cluster specifier
Overview
--------

The HTTP Lua cluster specifier allows `Lua <https://www.lua.org/>`_ scripts to select router cluster
during the request flows. `LuaJIT <https://luajit.org/>`_ is used as the runtime. Because of this, the
supported Lua version is mostly 5.1 with some 5.2 features. See the `LuaJIT documentation
<https://luajit.org/extensions.html>`_ for more details.
The HTTP Lua cluster specifier allows `Lua <https://www.lua.org/>`_ scripts to select a router cluster
during the request flow.

.. note::
`LuaJIT <https://luajit.org/>`_ is used as the runtime.

This means that the currently supported Lua version is mostly 5.1 with some 5.2 features.

See the `LuaJIT documentation <https://luajit.org/extensions.html>`_ for more details.

Configuration
-------------

* This filter should be configured with the type URL ``type.googleapis.com/envoy.extensions.router.cluster_specifiers.lua.v3.LuaConfig``.
* :ref:`v3 API reference <envoy_v3_api_msg_extensions.router.cluster_specifiers.lua.v3.LuaConfig>`

A simple example of configuring Lua cluster specifier is as follow:

.. code-block:: yaml
routes:
- match:
prefix: "/"
route:
inline_cluster_specifier_plugin:
extension:
name: envoy.router.cluster_specifier_plugin.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.router.cluster_specifiers.lua.v3.LuaConfig
source_code:
inline_string: |
function envoy_on_route(route_handle)
local header_value = route_handle:headers():get("header_key")
if header_value == "fake" then
return "fake_service"
end
return "web_service"
end
default_cluster: web_service
Lua script defined in ``source_code`` will be executed to select router cluster, and just as cluster specifier
plugin in C++, Lua script can also select router cluster based on request headers. If Lua script execute failure,
``default_cluster`` will be used.
A simple example configuration of a Lua cluster:

.. literalinclude:: /start/sandboxes/_include/lua-cluster-specifier/envoy.yaml
:language: yaml
:lines: 22-40
:emphasize-lines: 3-17
:linenos:
:caption: :download:`lua-cluster-specifier.yaml </start/sandboxes/_include/lua-cluster-specifier/envoy.yaml>`

The Lua script defined in
:ref:`source_code <envoy_v3_api_field_extensions.router.cluster_specifiers.lua.v3.LuaConfig.source_code>`
will be executed to select the routed cluster.

It can also select a cluster based on matched request headers.

If execution of the Lua script results in failure, the
:ref:`default_cluster <envoy_v3_api_field_extensions.router.cluster_specifiers.lua.v3.LuaConfig.default_cluster>`
will be used.

Complete example
----------------

A complete example using Docker is available in :repo:`/examples/lua-cluster-specifier`.
A complete example using Docker is available in the :ref:`Lua cluster specifier sandbox <install_sandboxes_lua_cluster_specifier>`.

Route handle API
----------------

When Envoy loads the script in the configuration, it looks for a global function that the script defines:
When Envoy loads the script in the configuration, it looks for a global function defined by the script:

.. code-block:: lua
function envoy_on_route(route_handle)
end
During the route path, Envoy will run *envoy_on_route* as a coroutine, passing a handle to the route API.
Following the route path, Envoy will run ``envoy_on_route`` as a coroutine, passing a handle to the route API.

The following methods on the stream handle are supported:
The following method on the stream handle is supported:

headers()
^^^^^^^^^
``headers()``
+++++++++++++

.. code-block:: lua
local headers = handle:headers()
local headers = route_handle:headers()
Returns the stream's headers. The headers can be used to match to select a specific cluster.
Returns the stream's headers. The headers can be used to select a specific cluster.

Returns a :ref:`header object <config_lua_cluster_specifier_header_wrapper>`.

Expand All @@ -80,13 +76,17 @@ Returns a :ref:`header object <config_lua_cluster_specifier_header_wrapper>`.
Header object API
-----------------

get()
^^^^^
``get()``
+++++++++

.. code-block:: lua
headers:get(key)
Gets a header. *key* is a string that supplies the header key. Returns a string that is the header
value or nil if there is no such header. If there are multiple headers in the same case-insensitive
key, their values will be combined with a *,* separator and returned as a string.
This method gets a header.

``key`` is a string that specifies the header key.

Returns either a string containing the header value, or ``nil`` if the header does not exist.

If there are multiple headers in the same case-insensitive key, their values will be concatenated to a string separated by ``,``.
22 changes: 10 additions & 12 deletions docs/root/start/sandboxes/lua-cluster-specifier.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _install_sandboxes_lua_cluster_specifier:

Lua Cluster Specifier
Lua cluster specifier
=====================

.. sidebar:: Requirements
Expand All @@ -17,13 +17,15 @@ The example Envoy proxy configuration includes a Lua cluster specifier plugin th

- ``envoy_on_route(route_handle)``

:ref:`See here <config_http_cluster_specifier_lua>` for an overview of Envoy's Lua cluster specifier
and documentation regarding the function.
.. tip::

See the :ref:`Lua cluster configuration documentation <config_http_cluster_specifier_lua>` for an overview and
documentation regarding the function.

Step 1: Build the sandbox
*************************

Change to the ``examples/lua-cluster-specifier`` directory.
Change to the ``examples/lua-cluster-specifier`` directory, and bring up the composition.

.. code-block:: console
Expand All @@ -35,27 +37,23 @@ Change to the ``examples/lua-cluster-specifier`` directory.
Name Command State Ports
--------------------------------------------------------------------------------------------
lua-cluster-specifier-proxy-1 /docker-entrypoint.sh /usr ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp
lua-cluster-specifier-web_service-1 /bin/echo-server Up 0.0.0.0:8080->8080/tcp
lua-cluster-specifier-proxy-1 /docker-entrypoint.sh /usr ... Up 10000/tcp, 0.0.0.0:10000->10000/tcp
Step 2: Send a request to the normal service
********************************************

The output from the ``curl`` command below should return 200, since the lua code select the normal service.

Terminal 1

.. code-block:: console
$ curl -i localhost:8000/anything 2>&1 |grep 200
$ curl -i localhost:10000/anything 2>&1 |grep 200
HTTP/1.1 200 OK
Step 3: Send a request to the fake service
******************************************

The output from the ``curl`` command below should return 503, since the lua code select the fake service.

Terminal 1
If you specify the request header ``header_key:fake``, curl will return a ``503`` response, as
the Lua code will select the fake service.

.. code-block:: console
Expand Down
8 changes: 1 addition & 7 deletions examples/lua-cluster-specifier/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,4 @@ services:
context: .
dockerfile: ../shared/envoy/Dockerfile
ports:
- "${PORT_PROXY:-8000}:8000"

web_service:
build:
context: ../shared/echo
ports:
- "${PORT_WEB:-8080}:8080"
- "${PORT_PROXY:-10000}:10000"
22 changes: 10 additions & 12 deletions examples/lua-cluster-specifier/envoy.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
static_resources:
listeners:
- name: main
address:
- address:
socket_address:
address: 0.0.0.0
port_value: 8000
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
Expand All @@ -13,9 +12,9 @@ static_resources:
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
name: example_route
virtual_hosts:
- name: local_service
- name: example_hosts
domains:
- "*"
routes:
Expand All @@ -32,23 +31,22 @@ static_resources:
function envoy_on_route(route_handle)
local header_value = route_handle:headers():get("header_key")
if header_value == "fake" then
return "fake_service"
return "fake_cluster"
end
return "web_service"
return "example_cluster"
end
default_cluster: web_service

default_cluster: example_cluster
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

clusters:
- name: web_service
type: STRICT_DNS # static
- name: example_cluster
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: web_service
cluster_name: example_cluster_service
endpoints:
- lb_endpoints:
- endpoint:
Expand Down

0 comments on commit 0edcdf8

Please sign in to comment.