diff --git a/Dockerfile b/Dockerfile index c2941d7..2bbbad6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,6 +7,7 @@ WORKDIR /code ENV GOARM 6 +RUN go get -d ./... RUN CGO_ENABLED=0 GOOS=linux GOARCH=$arch go build -a -installsuffix cgo http.go FROM scratch diff --git a/Dockerfile.1809 b/Dockerfile.1809 index dac0fcd..d1b7b35 100644 --- a/Dockerfile.1809 +++ b/Dockerfile.1809 @@ -1,4 +1,4 @@ -ARG golang=chocolateyfest/golang +ARG golang=golang:1.13-windowsservercore-1809 ARG target=mcr.microsoft.com/windows/nanoserver:1809 FROM $golang AS build @@ -6,6 +6,7 @@ FROM $golang AS build COPY . /code WORKDIR /code +RUN go get -d ./... RUN go build http.go FROM $target diff --git a/Dockerfile.windows b/Dockerfile.windows index 7fa7402..d1b7b35 100644 --- a/Dockerfile.windows +++ b/Dockerfile.windows @@ -1,4 +1,4 @@ -ARG golang=golang:nanoserver +ARG golang=golang:1.13-windowsservercore-1809 ARG target=mcr.microsoft.com/windows/nanoserver:1809 FROM $golang AS build @@ -6,6 +6,7 @@ FROM $golang AS build COPY . /code WORKDIR /code +RUN go get -d ./... RUN go build http.go FROM $target diff --git a/README.md b/README.md index 39d58d2..be0f885 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,26 @@ Simple HTTP docker service that prints it's container ID - for (almost) any Dock $ curl http://localhost:8080 I'm 736ab83847bb running on linux/amd64 + IP: 127.0.0.1 + IP: 172.17.0.2 + ENV: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + ENV: HOSTNAME=8b5485ce34ff + ENV: PORT=80 + ENV: HOME=/root + GET / HTTP/1.1 + Host: localhost + User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36 + Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 + Accept-Encoding: gzip, deflate, br + Accept-Language: en-US,en;q=0.9,de;q=0.8 + Cache-Control: no-cache + Connection: keep-alive + Pragma: no-cache + Sec-Fetch-Mode: navigate + Sec-Fetch-Site: none + Sec-Fetch-User: ?1 + Upgrade-Insecure-Requests: 1 + ## Windows $ docker run -d -p 8080:8080 --name whoami -t stefanscherer/whoami @@ -62,3 +82,10 @@ Image: stefanscherer/whoami - windows/amd64:10.0.16299.431 - windows/amd64:10.0.17134.48 ``` + +## Machine readable version +On the route /api the app will expose the same information as a json body + +``` +{"hostname":"8b5485ce34ff","platform":"linux/amd64","ip":["127.0.0.1","172.17.0.2"],"header":{"Accept":["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3"],"Accept-Encoding":["gzip, deflate, br"],"Accept-Language":["en-US,en;q=0.9,de;q=0.8"],"Connection":["keep-alive"],"Sec-Fetch-Mode":["navigate"],"Sec-Fetch-Site":["none"],"Sec-Fetch-User":["?1"],"Upgrade-Insecure-Requests":["1"],"User-Agent":["Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36"]},"env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","HOSTNAME=8b5485ce34ff","PORT=80","HOME=/root"]} +``` diff --git a/http.go b/http.go index f65877c..4589d67 100644 --- a/http.go +++ b/http.go @@ -1,25 +1,108 @@ package main import ( + "encoding/json" + "flag" "fmt" "log" + "net" "net/http" + "net/url" "os" "runtime" + "time" + + "gopkg.in/sirupsen/logrus.v1" + "gopkg.in/spf13/viper.v1" ) +type DataResponse struct { + Hostname string `json:"hostname,omitempty"` + Platform string `json:"platform,omitempty"` + IP []string `json:"ip,omitempty"` + Headers http.Header `json:"header,omitempty"` + Environment []string `json:"env,omitempty"` +} + +var port string + +func init() { + flag.StringVar(&port, "port", "8080", "give me a port number") + + lvl, err := logrus.ParseLevel(viper.GetString("loglevel")) + if err != nil { + lvl = logrus.WarnLevel + } + logrus.SetLevel(lvl) +} + func main() { - port := os.Getenv("PORT") - if port == "" { - port = "8080" + flag.Parse() + + http.HandleFunc("/", index) + http.HandleFunc("/api", api) + + log.Println("Starting up on port " + port) + if err := http.ListenAndServe(":"+port, nil); err != nil { + http.ListenAndServe(":"+port, nil) } +} + +func index(w http.ResponseWriter, req *http.Request) { + u, _ := url.Parse(req.URL.String()) + queryParams := u.Query() - fmt.Fprintf(os.Stdout, "Listening on :%s\n", port) + wait := queryParams.Get("wait") + if len(wait) > 0 { + duration, err := time.ParseDuration(wait) + if err == nil { + time.Sleep(duration) + } + } + + data := fetchData(req) + fmt.Fprintf(os.Stdout, "I'm %s\n", data.Hostname) + fmt.Fprintf(w, "I'm %s running on %s\n\n", data.Hostname, data.Platform) + + for _, ip := range data.IP { + fmt.Fprintln(w, "IP:", ip) + } + + for _, env := range data.Environment { + fmt.Fprintln(w, "ENV:", env) + } + req.Write(w) +} + +func api(w http.ResponseWriter, req *http.Request) { + data := fetchData(req) + json.NewEncoder(w).Encode(data) +} + +func fetchData(req *http.Request) DataResponse { hostname, _ := os.Hostname() - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(os.Stdout, "I'm %s\n", hostname) - fmt.Fprintf(w, "I'm %s running on %s/%s\n", hostname, runtime.GOOS, runtime.GOARCH) - }) + data := DataResponse{ + hostname, + fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + []string{}, + req.Header, + os.Environ(), + } + + ifaces, _ := net.Interfaces() + for _, i := range ifaces { + addrs, _ := i.Addrs() + for _, addr := range addrs { + var ip net.IP + switch v := addr.(type) { + case *net.IPNet: + ip = v.IP + case *net.IPAddr: + ip = v.IP + } + data.IP = append(data.IP, ip.String()) + } + } - log.Fatal(http.ListenAndServe(":"+port, nil)) + return data } diff --git a/test.ps1 b/test.ps1 index 2ac2bdd..d7366c8 100644 --- a/test.ps1 +++ b/test.ps1 @@ -14,8 +14,8 @@ Write-Host Starting container docker run --name whoamitest -p 8080:8080 -d whoami Start-Sleep 10 -docker logs whoamitest - $ErrorActionPreference = 'SilentlyContinue'; + +docker logs whoamitest docker kill whoamitest docker rm -f whoamitest