All Projects → myteksi → ego-demo

myteksi / ego-demo

Licence: Apache-2.0 License
Envoy filters in Go

Programming Languages

go
31211 projects - #10 most used programming language
C++
36643 projects - #6 most used programming language
Starlark
911 projects
c
50402 projects - #5 most used programming language
python
139335 projects - #7 most used programming language
shell
77523 projects

Projects that are alternatives of or similar to ego-demo

image-hub
Image Hub is a sample application for exploring WebAssembly modules used as Envoy filters.
Stars: ✭ 56 (+64.71%)
Mutual labels:  envoy-filter, envoy-proxy, envoy-filters
meshem
A simple implementation for Envoy's control plane
Stars: ✭ 22 (-35.29%)
Mutual labels:  envoy, envoy-proxy
yastack
YAStack: User-space network-stack based on DPDK, FreeBSD TCP/IP Stack, EnvoyProxy
Stars: ✭ 90 (+164.71%)
Mutual labels:  envoy, envoy-proxy
Gloo
The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy
Stars: ✭ 3,219 (+9367.65%)
Mutual labels:  envoy, envoy-proxy
Ambassador
open source Kubernetes-native API gateway for microservices built on the Envoy Proxy
Stars: ✭ 3,583 (+10438.24%)
Mutual labels:  envoy, envoy-proxy
envoy-proxy-demos
Set of Envoy Proxy feature demos (Envoy v2 API supported)
Stars: ✭ 63 (+85.29%)
Mutual labels:  envoy, envoy-proxy
envoy-nats-streaming
No description or website provided.
Stars: ✭ 28 (-17.65%)
Mutual labels:  envoy, envoy-filter
flightpath
XDS to run Envoy as an edge proxy for Consul Connect.
Stars: ✭ 15 (-55.88%)
Mutual labels:  envoy, envoy-proxy
marin3r
Lightweight, CRD based envoy control plane for kubernetes
Stars: ✭ 51 (+50%)
Mutual labels:  envoy
kubernetes workshop
Kubernetes is an open source Container Orchestration System for automatic deployment, scaling, and management of Containerized application. Kubernetes gives you the freedom to take advantage of on-premise, hybrid or public cloud infrastructure. Kubernetes helps you to scale both horizontally and vertically depends on the load.
Stars: ✭ 27 (-20.59%)
Mutual labels:  envoy
engarde
Parse default envoy (and istio-proxy) access logs like a champ with engarde and jq
Stars: ✭ 82 (+141.18%)
Mutual labels:  envoy
laravel-envoy-scripts
Here I have compiled my Laravel Envoy scripts to deploy different projects.
Stars: ✭ 16 (-52.94%)
Mutual labels:  envoy
kourier
Kourier is a Knative Serving Ingress. It has been adopted by Knative, and we keep developing it at: github.com/knative/net-kourier
Stars: ✭ 47 (+38.24%)
Mutual labels:  envoy
envoyproxy doc ZH CN
envoyproxy 智能代理中文参考文档 v1.5.0
Stars: ✭ 75 (+120.59%)
Mutual labels:  envoy
grpc-web-chat
A simple project demonstrating how both a Go and Java back end can power the same Vue.js front end using gRPC.
Stars: ✭ 21 (-38.24%)
Mutual labels:  envoy-proxy
sample-envoy-proxy
custom implementation of service discovery with envoy and inter-service communication for spring-boot applications
Stars: ✭ 29 (-14.71%)
Mutual labels:  envoy
proxy-wasm-cpp-host
WebAssembly for Proxies (C++ host implementation)
Stars: ✭ 55 (+61.76%)
Mutual labels:  envoy
oidc-filter
A WASM plugin for Envoy supporting the Open ID Connect Authorization Flow, extending Istio's JWT functionality
Stars: ✭ 40 (+17.65%)
Mutual labels:  envoy
atlas
Secure Distributed Thanos Deployment using an Observability Cluster
Stars: ✭ 39 (+14.71%)
Mutual labels:  envoy
meshery
Meshery, the cloud native manager
Stars: ✭ 1,587 (+4567.65%)
Mutual labels:  envoy

EGo-Demo

EGo Splash

This is a demo of how to build a Golang filter for Envoy, based on the Envoy Filter Example project, by using Go's CGo feature.

It is still a little rough on the edges, though probably good enough to help understand most of the challenges and benefits of this approach.

Design Principles

  • Provide a Go-native experience for Go developers
  • Support zero-copy data access where possible
  • Unopinionated interface: reflect the envoy C++ interface classes as close as possible

Successes

  • Parsing and passing filter configuration from C to Go with zero-copy and leveraging Envoy's protobuf validation mechanism
  • Communication between C and Go with zero-copy and strongly parallel interface design
  • Allow the use of goroutines with minimal discipline required (Pin/Post/Unpin)
  • Creating new filters without having to touch C code (except when "lifting up" new envoy interfaces)
  • Support interactions with SDS via Envoy's built-in client

Challenges

This project is still in its infancy, and there are a couple of technical challenges still waiting to be solved.

Dependency Cycles

In order to call Go functions from C, the go libraries need to be built first (as this produces the required C headers). However, the Go libraries also have a dependency on C libraries (to facilitate calls to envoy functions).

This can, in most cases, be mitigated by careful separation of the functions needed for the Go->C interactions from the functions implementing the envoy L7 filter interfaces.

When there are functions that are needed on both sides, this often requires creativity. A good example for this is the onPost handler, which needs to be passed as a callback on the Go->C side, but has an implementation that needs to make a C->Go call.

Since this obviously isn't a limitation of linkers or C, the situation could probably mitigated by extending the Bazel tooling (for example, by separating the generation of Go C headers and the Go library).

CGo limitations

Currently, there can only be one CGo library, and its main() function needs to reside in the same package containing the CGo code. This means that egofilters needs to be referenced from the ego package and can't contain CGo code. This is probably the most significant issue because it is in direct opposition to the desired architecture.

Replication of Envoy classes as Go interfaces

This is a work intensive process, and the only reason we chose to take on this challenge is that it typically is a one-off effort that will become less notable over time.

Keeping up with Envoy's changing C++ interface also requires regular effort, and in fact, this project currently doesn't account for different Envoy versions, although it probably should.

Prerequisites

Bazel

MacOS

To set up bazel on MacOS, install Homebrew and then

brew install bazelbuild/tap/bazelisk
brew install coreutils wget cmake libtool go bazel automake ninja clang-format autoconf aspell

(Don't worry if you get a warning for a symlink that couldn't be updated because bazelisk is sitting on it -- this is by design)

Building

git submodule update --init  # clone the linked envoy tag into /envoy
bazel build //:envoy         # build envoy with the new libraries added

Note: This version requires Envoy v1.14

Trying It Out

This demo includes two example filters:

  • getheader is a very basic filter that showcases using go-routines and the Go runtime library for HTTP requests. Its sole purpose is to retrieve response header hdr from a GET request for URL src, and inject it as request header key into the request to the upstream service.

  • security is a more elaborate piece outlining a framework to accomodate many different custom authentication methods, to show how things might pan out at scale. This is showcased via a simple pseudo-HMAC filter with the actual checksum calculations delegated to a separate REST service to once more demonstrate how to align Go-routines and envoy worker threads as well as to motivate the use of SDS based secrets.

To play with it, go to the repository root, and do

bazel run ego-demo

This spins up a simple echo service as upstream for all requests, an HMAC authentication provider sidecar, and the Envoy proxy configured to showcase the Go-based filters provided with this demo.

curl -iX GET 'http://127.0.0.1:8080/Hello,world!'

Note the X-Getheader-Result in the response which was injected into the request by the getheader filter

curl -iX GET 'http://127.0.0.1:8080/hmac/unsigned' -H 'Authorization: client_id:123'

This should produce a 401 Unauthorized response

curl -iX GET 'http://127.0.0.1:8080/hmac/unsigned' -H 'Authorization: client_id:17'

The expectation would be a 200 OK response.

curl -iX GET 'http://127.0.0.1:8080/hmac/signed' -H 'Authorization: client_id:15'

This should also result in a 200 OK response, and a x-custom-auth-signature-hmac-sha256: 200_nnn response header (which clearly isn't the SHA256 HMAC but just the status code with the length of the response body appended).

Tinkering

The Go code is integrated with bazel via rules_go. The bazel rules areautomatically generated by gazelle, and interfaces mocks are generated via mockery.

Running Tests

The EGo interface layer still deserves a bit more rigorous testing, only some mind-numbing permutation testing for the most critical pieces has already been implemented so far, please budget a couple of minutes for this to run.

bazel test //ego/...

Since the HMAC filter is a gutted version of a more elaborate thing, coverage is relatively good (although not very pretty to read).

bazel test //egofilters/...

Note for MacOS users

Please see Envoy issue #10478 if some of the C++ tests fail with this message:

dyld: Symbol not found: _program_invocation_name

This is most likely means XCode needs to be installed.

Updating the Go Rules

From the repository root, do

bazel run gazelle

Adding new Go Dependencies

From the repository root, do

bazel run //:gazelle -- update-repos -from_file=go.mod

Bazel and Go Interface Mocks

Make sure you have installed mockery. Then, from the repository root, do

tools/copy_pb_go.py  # update generated protobuf bindings

cd egofilters/mock
go generate

cd ../../ego/test/go/mock
go generate

cd ../../../..
bazel run gazelle    # just in case

Bazel integration of this is work in progress...

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].