Last active
November 1, 2020 16:43
-
-
Save nicolai86/5ffe8905ab2c16cf0b3eb8f054bae456 to your computer and use it in GitHub Desktop.
AWS es Proxy in go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks, it worked instantly !
For those who start from scratch like me: