Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Build StatusLicense

Universal Gateway with OpenAPI Spec and Advanced Rate-limiting built on Envoy Proxy

Run Any[where] - Any[Platform | Cloud | Service]

Universal Control Plane that drives Envoy (or a Fleet of Envoy's). Runs as Kubernetes Ingress Gateway | Standalone Gateway | Stateless SideCar Gateways

Kubernetes Ingress
Standalone

enroutectl: Program OpenAPI Spec on Enroute Universal API Gateway in a minute

enroutectl openapi --openapi-spec petstore.json --to-standalone-url http://localhost:1323/

Extend using Global HTTP Filters and Route Filters

You can associate additional plugin/filter functionality at global level or route level.

Filters/Plugins are supported for both Kubernetes Ingress Gateway and Standalone Gateway.

Config Model

Drive Enroute using REST or GraphQL APIs, Kubernetes CRDs or enroutectl cli

Enroute provides several options to populate the xDS cache for the underlying Envoy.

It has simple REST APIs and a GraphQL interface.
    curl -X POST "http://localhost:1323/service"         \
      -d 'Service_Name=openapi-enroute'                  \
      -d 'Fqdn=saaras.io'
    
    curl -X POST "http://localhost:1323/service/openapi-enroute/route"  \
      -d 'Route_Name=root-slash'                                        \
      -d 'Route_prefix=/'
                             
    curl -X POST "http://localhost:1323/upstream"     \
      -d 'Upstream_name=openapi-upstream'             \
      -d 'Upstream_ip=openapi.example.com'            \
      -d 'Upstream_port=9001'                         \
      -d 'Upstream_hc_path=/'                         \
      -d 'Upstream_weight=100'
                            

Rate Limit Filter

curl -s localhost:1323/filter/route_rl_1 | jq
{
  "data": {
    "saaras_db_filter": [
      {
        "filter_id": 139,
        "filter_name": "route_rl_1",
        "filter_type": "route_filter_ratelimit",
        "filter_config": {
          "descriptors": [
            {
              "generic_key": {
                "descriptor_value": "default"
              }
            }
          ]
        }
      }
    ]
  }
}

GlobalConfig for Standalone Gateway

curl -s localhost:1323/globalconfig/t1 | jq
{
  "data": {
    "saaras_db_globalconfig": [
      {
        "globalconfig_id": 237,
        "globalconfig_name": "gc1",
        "globalconfig_type": "globalconfig_ratelimit",
        "config_json": {
          "domain": "enroute",
          "descriptors": [
            {
              "key": "generic_key",
              "value": "default",
              "rate_limit": {
                "unit": "second",
                "requests_per_unit": 10
              }
            }
          ]
        }
      }
    ]
  }
}
It can be programmed using the enroutectl CLI

Program an OpenAPI Spec on Enroute Standalone Gateway or Kubernetes Ingress Gateway

enroutectl openapi --openapi-spec petstore.json --to-standalone-url http://localhost:1323/
When running at Kubernetes Ingress, CRDs can be used to program it

Creating a GatewayHost that maps to a VirtualHost

---
apiVersion: enroute.saaras.io/v1beta1

kind: GatewayHost
metadata:
  labels:
    app: httpbin
  name: httpbin
  namespace: enroute-gw-k8s
spec:
  virtualhost:
    fqdn: demo.saaras.io
    filters:
      - name: luatestfilter
        type: http_filter_lua
  routes:
    - match: /
      services:
        - name: httpbin
          port: 80
      filters:
        - name: rl2
          type: route_filter_ratelimit
---

Creating a RouteFilter that attaches to a GatewayHost Route

apiVersion: enroute.saaras.io/v1beta1
kind: RouteFilter
metadata:
  labels:
    app: httpbin
  name: rl2
  namespace: enroute-gw-k8s
spec:
  name: rl2
  type: route_filter_ratelimit
  routeFilterConfig:
    config: |
        {
            "descriptors": [
              {
                "request_headers": {
                  "header_name": "x-app-key",
                  "descriptor_key": "x-app-key"
                }
              },
              {
                "remote_address": "{}"
              }
            ]
        }
---

Creating a HttpFilter that can be attached to a GatewayHost

apiVersion: enroute.saaras.io/v1beta1
kind: HttpFilter
metadata:
  labels:
    app: httpbin
  name: luatestfilter
  namespace: enroute-gw-k8s
spec:
  name: luatestfilter
  type: http_filter_lua
  httpFilterConfig:
    config: |
        function get_api_key(path, q_param_name)
            -- path = "/?api-key=valid-key"
            s, e = string.find(path, "?")
            if s ~= nil then
              for pre, q_params in string.gmatch(path, "(%S+)?(%S+)") do
                -- print(pre, q_params, path, s, e)
                for k, v in string.gmatch(q_params, "(%S+)=(%S+)") do
                  print(k, v)
                  if k == q_param_name then
                    return v
                  end
                end
              end
            end

            return nil
        end

        function envoy_on_request(request_handle)
           request_handle:logInfo("Begin: envoy_on_request()");

           hdr_x_app_key = "x-app-key"
           hdr_x_app_not_found = "x-app-notfound"
           q_param_name = "api-key"

           -- extract API key from header "x-app-key"
           headers = request_handle:headers()
           header_value = headers:get(hdr_x_app_key)

           if header_value ~= nil then
             request_handle:logInfo("envoy_on_request() API Key from header "..header_value);
           else
             request_handle:logInfo("envoy_on_request() API Key in header is nil");
           end

           -- extract API key from query param "api-key"
           path_in = headers:get(":path")
           api_key = get_api_key(path_in, q_param_name)

           if api_key ~= nil then
             request_handle:logInfo("envoy_on_request() API Key from query param "..api_key);
           else
             request_handle:logInfo("envoy_on_request() API Key from query param is nil");
           end

           -- If API key found, do nothing
           -- else set header x-app-key:x-app-notfound
           if header_value == nil then
               if api_key == nil then
                 headers:add(hdr_x_app_key, hdr_x_app_not_found)
               else
                 headers:add(hdr_x_app_key, api_key)
               end
           end

           request_handle:logInfo("End: envoy_on_request()");

        end

        function envoy_on_response(response_handle)
           response_handle:logInfo("Begin: envoy_on_response()");
           response_handle:logInfo("End: envoy_on_response()");
        end
---

Creating GlobalConfig to program advanced rate-limit engine config

---
apiVersion: enroute.saaras.io/v1beta1

kind: GlobalConfig
metadata:
  labels:
    app: httpbin
  name: rl-global-config
  namespace: enroute-gw-k8s
spec:
  name: rl-global-config
  type: globalconfig_ratelimit
  config: |
        {

          "domain": "enroute",
          "descriptors" :
          [
            {
              "key" : "generic_key",
              "value" : "default",
              "rate_limit" :
              {
                "unit" : "second",
                "requests_per_unit" : 10
              }
            }
          ]
        }
---

Grafana Telemetry for Standalone Gateway

Grafana Telemetry on Standalone Gateway

Why Enroute?

Digital transformation is a key initiative in organizations to meet business requirements . This need is driving cloud adoption with a more self-serve DevOps driven approach. Application and micro-services are run in Kubernetes and in public/private cloud with an automated continous delivery pipeline.

As applications undergo this change, traditional API gateways are retrofitted to meet the changing requirements. This has resulted in multiple API gateways and different solutions that work only in a subset of use-cases. An API gateway that works for traditional as well as new cloud-native use-cases is critical as an application undergoes this transition.

Enroute is built from ground-up to support both traditional and cloud native use-cases. Enroute can be deployed in multiple topolgies to meet the demands of todays application, regardless of where an application is in the cloud journey. The same gateway can be deployed outside kubernetes in Standalone mode for traditional use cases, a kubernetes ingress controller and also inside kubernetes.

Enroute's powerful API brings automation and enables developer operations to treat infrastructure as code. Enroute natively supports advanced rate-limiting and lua scripting as extensible filters or plugins that can be attached either for per-route traffic or all traffic. Enroute API Gateway control plane drives one or many data planes built using Envoy Proxy

Getting Started

Blogs, Cookbooks, getting started, examples and additional documentation can be found at

You can’t perform that action at this time.