From cea1ae23ac0e27dc35a497f437b33053012a1a10 Mon Sep 17 00:00:00 2001 From: Marcus Noble Date: Sun, 8 Aug 2021 16:13:11 +0100 Subject: [PATCH] Initial commit --- Dockerfile | 13 ++++++++++++ Makefile | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 11 ++++++++++ go.mod | 3 +++ main.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 README.md create mode 100644 go.mod create mode 100644 main.go diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6d6c394 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,13 @@ +FROM golang:1.16-alpine AS builder +RUN apk update && apk add --no-cache git && apk add -U --no-cache ca-certificates +WORKDIR /app/ +ADD go.mod ./ +RUN go mod download +ADD . . +RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-w -s" -o echoserver . + +FROM scratch +WORKDIR /app/ +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ +COPY --from=builder /app/echoserver /app/echoserver +ENTRYPOINT ["/app/echoserver"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..13d5c71 --- /dev/null +++ b/Makefile @@ -0,0 +1,61 @@ +.DEFAULT_GOAL := default + +IMAGE ?= docker.cluster.fun/averagemarcus/echoserver:latest + +.PHONY: test # Run all tests, linting and format checks +test: lint check-format run-tests + +.PHONY: lint # Perform lint checks against code +lint: + @go vet && golint -set_exit_status ./... + +.PHONY: check-format # Checks code formatting and returns a non-zero exit code if formatting errors found +check-format: + @gofmt -e -l . + +.PHONY: format # Performs automatic format fixes on all code +format: + @gofmt -s -w . + +.PHONY: run-tests # Runs all tests +run-tests: + @echo "⚠️ 'run-tests' unimplemented" + +.PHONY: fetch-deps # Fetch all project dependencies +fetch-deps: + @go mod tidy + +.PHONY: build # Build the project +build: lint check-format fetch-deps + @go build -o echoserver main.go + +.PHONY: docker-build # Build the docker image +docker-build: + @docker build -t $(IMAGE) . + +.PHONY: docker-publish # Push the docker image to the remote registry +docker-publish: + @docker push $(IMAGE) + +.PHONY: run # Run the application +run: + @go run . + +.PHONY: ci # Perform CI specific tasks to perform on a pull request +ci: + @echo "⚠️ 'ci' unimplemented" + +.PHONY: release # Release the latest version of the application +release: + @kubectl --namespace echoserver rollout restart deployment echoserver + +.PHONY: help # Show this list of commands +help: + @echo "echoserver" + @echo "Usage: make [target]" + @echo "" + @echo "target description" | expand -t20 + @echo "-----------------------------------" + @grep '^.PHONY: .* #' Makefile | sed 's/\.PHONY: \(.*\) # \(.*\)/\1 \2/' | expand -t20 + +default: test build diff --git a/README.md b/README.md new file mode 100644 index 0000000..ed27fb2 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# echoserver + +A basic HTTP server to echo back details of a request + +## Contributing + +If you find a bug or have an idea for a new feature please [raise an issue](issues/new) to discuss it. + +Pull requests are welcomed but please try and follow similar code style as the rest of the project and ensure all tests and code checkers are passing. + +Thank you 💛 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..70a3f40 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/averagemarcus/echoserver + +go 1.16 diff --git a/main.go b/main.go new file mode 100644 index 0000000..874e881 --- /dev/null +++ b/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "encoding/json" + "log" + "net" + "net/http" + "os" + "time" +) + +type echoResponse struct { + RequestPath string `json:"requestPath"` + RequestHost string `json:"requestHost"` + Protocol string `json:"protocol"` + Method string `json:"method"` + Headers map[string][]string `json:"headers"` + RemoteAddr string `json:"remoteAddr"` + + ServerHostname string `json:"serverHostname"` + ServerIP string `json:"serverIP"` + DateTime time.Time `json:"dateTime"` +} + +func main() { + hostname, _ := os.Hostname() + conn, _ := net.Dial("udp", "8.8.8.8:80") + defer conn.Close() + ipAddress := conn.LocalAddr().String() + + http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) { + resp := echoResponse{ + RequestPath: r.URL.String(), + RequestHost: r.Host, + Protocol: r.Proto, + Method: r.Method, + Headers: r.Header, + RemoteAddr: r.RemoteAddr, + ServerHostname: hostname, + ServerIP: ipAddress, + DateTime: time.Now(), + } + + b, _ := json.Marshal(resp) + + rw.Header().Add("Content-Type", "application/json") + rw.Write(b) + }) + + err := http.ListenAndServe(":8080", nil) + if err != nil { + log.Fatal(err) + } +}