Version 2.1 of the HAProxy Data Plane API expands support to all available request and response actions, adds Lua actions, and improves file handling.
A year ago, we introduced version 1.0 of the HAProxy Data Plane API, enabling you to configure your HAProxy load balancers remotely through a modern RESTful HTTP API. That first version of the API focused on the essential behaviors for creating frontend proxies, backend server pools, ACLs and traffic switching rules. The list of features has continued to expand since then, culminating in this most recent version, 2.1.
Version 2.1 follows up on the recent 2.0 release and puts the focus on request and response actions that allow HAProxy to shape traffic, modify requests, track behavior, and drop connections dynamically. This includes custom Lua actions that you define and load into HAProxy. This version also accumulates bug fixes and other improvements made since the initial release and we have improved how the file handling in the HAProxy Data Plane API works, making it more robust. We’ll cover what changed and the issues we faced there.
Another key feature added was serving an OpenAPI v3-compatible version of the specification together with the v2 version (formerly known as Swagger). The HAProxy Data Plane API is built using the Open API 2.0 specification, and on its /specification endpoint it serves that version in JSON format. You can use that endpoint to build your own client libraries and then consume the API in any language you would like. You’ll find some helpful examples of how to do that in our blog post HAProxy Go Packages Ecosystem. Since the initial release, the Open API specification has moved to version 3.0 and some helpful tools for generating code, creating documentation, and publishing simple UIs rely on that newer version. To support people wishing to use these tools, and to move the HAProxy Data Plane API forward, it now serves a v3-compatible specification at the /specification_openapiv3 endpoint, in the JSON format.
Request and response actions
For this version, we set our focus on expanding the
http-response directives to support all available actions. This unlocks some of the most powerful capabilities of HAProxy, including the ability to set the priority of different requests, change attributes of an HTTP message, silently drop malicious users, and track clients across requests.
The following actions are now supported on the /services/haproxy/configuration/http_request_rules endpoints:
- sc-inc-gpc0, sc-inc-gpc1, sc-set-gpt0
- set-dst, set-dst-port
- set-src, set-src-port
The following actions are now supported on the /services/haproxy/configuration/http_response_rules endpoints:
- sc-inc-gpc0, sc-inc-gpc1, sc-set-gpt0
One of the advantages of using HAProxy is having the ability to extend the load balancer with your own, custom, Lua code. With this version of the API, you can load Lua modules at startup and insert your Lua actions into the request and response pipelines. You can learn more about how to integrate HAProxy with Lua by reading our blog post 5 Ways to Extend HAProxy with Lua. If your version of HAProxy is compiled with Lua support, you can use the API’s /services/haproxy/configuration/global endpoint to add
lua-load directives to the
global section of your configuration. Here’s an example:
We’ve added support for configuring HAProxy to call your Lua action with the
tcp-response directives. So, you can invoke your Lua action like this, which places an
http-request lua line into a
frontend named http-1:
This would produce a configuration like this:
Robust file handling
On some rare occasions, the Data Plane API was truncating the resulting HAProxy configuration file down to zero bytes after a transaction was committed. This was happening because the file-copy from the transaction file to the actual configuration file wasn’t truly atomic, as there were two actions being executed. First, we were creating the file, which happened when the code called the Golang method
os.Create, and then we were copying the updated contents to the file with
os.Create truncates the destination file, but in some cases, something went wrong and
io.Copy was never called.
Identifying this we switched the HAProxy config-parser library to use the google/renameio package to ensure the atomicity of the operation. Now the Data Plane API uses the newer version of the config-parser library, which writes files using
renameio.WriteFile. Also, we are no longer copying from the transaction file to the destination HAProxy configuration file, but are instead using the in-memory state of the config-parser to write the configuration file. This way, we eliminate the issue of moving files across different filesystems.
Other minor changes
In addition to the changes mentioned above, the 2.1 version includes bug fixes that were added in minor releases since the 2.0 version and other improvements.
proxy-v2-optionsfields to the /services/haproxy/configuration/server endpoint
ssl-default-server-ciphersuitesto the /services/haproxy/configuration/global endpoint
- You can now fetch and work with map files that are located outside the configured
maps-dirdirectory on the /services/haproxy/runtime/maps endpoint
We’d like to thank the code contributors who helped make this version possible:
|Amel Husić||FEATURE BUG|
|Marko Juraga||BUILD FEATURE BUG|
|Zlatko Bratkovic||FEATURE BUG|
The HAProxy Data Plane API version 2.1 expands the set of features to cover more of the dynamic capabilities that are unique to HAProxy, including the ability to load and call your own Lua actions. It includes several bug fixes, including a bug that truncated the configuration file under some conditions. The API continues to get better thanks to the active community surrounding it. If you’d like to get involved, head over to our GitHub repository to learn more!