Create a gist now

Instantly share code, notes, and snippets.

@nicolai86 /main.go
Last active Aug 15, 2017

What would you like to do?
AWS es Proxy in go
package main
import (
"bytes"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"net/http/httputil"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol/rest"
)
func main() {
flag.Parse()
if len(flag.Args()) != 1 {
log.Fatalln("Please provide an AWS es cluster URL.")
}
var esCluster = flag.Args()[0]
if esCluster == "" {
log.Fatalln("Please provide an AWS es cluster URL.")
}
if hosts, err := net.LookupHost(esCluster); err != nil {
log.Printf("Failed to resolve es cluster: %v.\n", err)
} else {
log.Printf("%q resolves to %#v.\n", esCluster, hosts)
}
var creds *credentials.Credentials
var region = strings.Split(esCluster, ".")[1]
fmt.Printf(`
__________ _________ _________________ ________ ______
___ |_ | / /_ ___/ ___ ____/_ ___/ ___ __ \________________ ______ ____ /
__ /| |_ | /| / /_____ \ __ __/ _____ \ __ /_/ /_ ___/ __ \_ |/_/_ / / /_ /
_ ___ |_ |/ |/ / ____/ / _ /___ ____/ / _ ____/_ / / /_/ /_> < _ /_/ / /_/
/_/ |_|___/|__/ /____/ /_____/ /____/ /_/ /_/ \____//_/|_| _\__, / (_)
/____/
Connected to %s
AWS ES cluster available at http://127.0.0.1:9200
Kibana available at http://127.0.0.1:9200/_plugin/kibana/
`, esCluster)
creds = credentials.NewSharedCredentials("", "")
if _, err := creds.Get(); err != nil {
creds = credentials.NewEnvCredentials()
if _, err = creds.Get(); err != nil {
log.Fatalf("Failed to load credentials: %v", err)
}
}
signer := v4.NewSigner(creds)
director := func(req *http.Request) {
req.URL.Scheme = "https"
req.Host = esCluster
req.URL.Host = esCluster
req.Header.Set("Connection", "close")
if req.Header.Get("Expect") != "" {
req.Header.Del("Expect")
}
if strings.Contains(req.URL.RawPath, "%2C") {
req.URL.RawPath = rest.EscapePath(req.URL.RawPath, true)
}
fmt.Printf("%s %s\n", req.Method, req.URL.Path)
t := time.Now()
req.Header.Set("Date", t.Format(time.RFC3339))
if req.Method != http.MethodGet && req.Method != http.MethodHead {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Fatal(err)
}
req.Body = ioutil.NopCloser(bytes.NewReader(buf))
if _, err := signer.Sign(req, bytes.NewReader(buf), "es", region, t); err != nil {
log.Printf("failed to sign: %v", err)
}
} else {
buf := bytes.Buffer{}
req.Body = ioutil.NopCloser(&buf)
if _, err := signer.Sign(req, bytes.NewReader(buf.Bytes()), "es", region, t); err != nil {
log.Printf("failed to sign: %v", err)
}
}
}
proxy := &httputil.ReverseProxy{Director: director}
log.Printf("[INFO] %v", http.ListenAndServe(":9200", proxy))
}

Pierozi commented Jul 9, 2017

Thanks, work like a charm.

Excellent, thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment