Skip to content

Commit

Permalink
Merge pull request #4 from williamchanrico/first_release
Browse files Browse the repository at this point in the history
Change go app structure and tag first release
  • Loading branch information
williamchanrico authored Apr 17, 2019
2 parents cbecc3c + 21daafd commit 0daf6eb
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .drone.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ steps:
repo: williamchanrico/debugapp
tags:
- latest
- 0.1.0
- 1.0.0
username:
from_secret: DOCKER_USERNAME
password:
Expand Down
6 changes: 4 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
FROM alpine:3.9

RUN apk update && apk add --no-cache \
ca-certificates \
bash \
sudo \
jq \
Expand All @@ -23,7 +24,8 @@ RUN apk update && apk add --no-cache \
busybox-extras

COPY entrypoint.sh .
COPY bin/install-to-container/httpstat /bin/
COPY bin/install-to-container/httpstat /bin/httpstat
COPY bin/debugapp /bin/debugapp

ENTRYPOINT ["./entrypoint.sh"]
WORKDIR /root
ENTRYPOINT ["/entrypoint.sh"]
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ REVISION := $(shell git rev-parse --short HEAD 2>/dev/null)
VERSION := $(shell git describe --tags --abbrev=0 2>/dev/null)

ifndef REVISION
override REVISION = asdfjkl
override REVISION = none
endif

ifndef VERSION
Expand Down Expand Up @@ -41,23 +41,24 @@ go-build: main.go ## Build the app (linux, use go-cross-build for other platfor
.PHONY: go-run
go-run: ## Run the app
make go-build
$(BIN_DIRECTORY)/$(APP_NAME) -port 8080
$(BIN_DIRECTORY)/$(APP_NAME) --http-port 8080 --https-port 8443

.PHONY: go-cross-build
go-cross-build: ## Build the app for multiple platforms
@mkdir -p $(BIN_DIRECTORY) | true
@mkdir -p $(BIN_DIRECTORY) || true
@# darwin
@for arch in "amd64" "386"; do \
CGO_ENABLED=0 GOOS=darwin GOARCH=$${arch} make go-build; \
sleep 0.5; \
tar cf $(BIN_DIRECTORY)/$(APP_NAME)_$(APP_VERSION)_darwin_$${arch}.tar $(BIN_DIRECTORY)/$(APP_NAME); \
tar czf $(BIN_DIRECTORY)/$(APP_NAME)_$(APP_VERSION)_darwin_$${arch}.tar.gz $(BIN_DIRECTORY)/$(APP_NAME); \
done;
@# linux
@for arch in "amd64" "386" "arm64"; do \
CGO_ENABLED=0 GOOS=linux GOARCH=$${arch} make go-build; \
sleep 0.5; \
tar cf $(BIN_DIRECTORY)/$(APP_NAME)_$(APP_VERSION)_linux_$${arch}.tar $(BIN_DIRECTORY)/$(APP_NAME); \
tar czf $(BIN_DIRECTORY)/$(APP_NAME)_$(APP_VERSION)_linux_$${arch}.tar.gz $(BIN_DIRECTORY)/$(APP_NAME); \
done;
@rm -rf $(BIN_DIRECTORY)/$(APP_NAME)

# DOCKER TASKS
# Build the container
Expand All @@ -68,6 +69,7 @@ docker-build: ## Build the container

.PHONY: docker-run
docker-run: ## Run container
@make docker-stop || true
docker run -dit -p 8080:80 --name $(DOCKER_CONTAINER_NAME) $(DOCKER_IMAGE_TAG):$(DOCKER_IMAGE_VERSION)
@docker exec -it $(DOCKER_CONTAINER_NAME) /bin/bash
@make docker-stop || true
Expand Down
Empty file removed bin/.gitkeep
Empty file.
Binary file modified bin/debugapp
Binary file not shown.
87 changes: 87 additions & 0 deletions debugapp/debugapp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package debugapp

import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"

"log"
)

// Response is the structure returned by the echo server.
type Response struct {
Host string `json:"host"`
Method string `json:"method"`
URI string `json:"uri"`
HTTPVersion string `json:"httpVersion"`
Time time.Time `json:"time"`
RemoteAddr string `json:"remoteAddr"`
TLS bool `json:"tls"`
Header map[string][]string `json:"header"`
Msg string `json:"message"`
}

// RunHTTPServer runs HTTP and HTTPS goroutines and blocks.
func RunHTTPServer(ctx context.Context) {
http.HandleFunc("/", debugapp)

go func() {
if AppFlag.HTTPSPort == 0 {
return
}

server := &http.Server{Addr: fmt.Sprintf(":%d", AppFlag.HTTPSPort)}
cert, key := createCert()
err := server.ListenAndServeTLS(cert, key)
if err != nil {
log.Fatal(err)
}

<-ctx.Done()
server.Shutdown(ctx)
}()

go func() {
if AppFlag.HTTPPort == 0 {
return
}

server := &http.Server{Addr: fmt.Sprintf(":%d", AppFlag.HTTPPort)}
err := server.ListenAndServe()
if err != nil {
log.Fatal(err)
}

<-ctx.Done()
server.Shutdown(ctx)
}()

<-ctx.Done()
}

func debugapp(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")

resp := Response{
Host: r.Host,
Method: r.Method,
URI: r.RequestURI,
HTTPVersion: fmt.Sprintf("%d.%d", r.ProtoMajor, r.ProtoMinor),
Time: time.Now(),
RemoteAddr: r.RemoteAddr,
Header: r.Header,
TLS: r.TLS != nil,
Msg: "Hello, you've reached DebugApp!",
}

respJSON, err := json.MarshalIndent(resp, "", " ")
if err != nil {
log.Printf("failed to marshal the resp: %v", err)
return
}

w.WriteHeader(http.StatusOK)
w.Write(respJSON)
}
35 changes: 35 additions & 0 deletions debugapp/envflags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package debugapp

import (
"flag"
"os"
)

// AppFlag contains variables from command-line flags
var AppFlag struct {
HTTPPort int
HTTPSPort int
}

// AppEnv contains variables from env
var AppEnv struct {
Dummy string
}

func init() {
AppEnv.Dummy = mustGetenv("DUMMY_NOT_USED", "DUMMY_DEFAULT_VALUE")
}

// RegisterFlags creates flags.
func RegisterFlags() {
flag.IntVar(&AppFlag.HTTPPort, "http-port", 8080, "Port for HTTP, 0 will disable this protocol")
flag.IntVar(&AppFlag.HTTPSPort, "https-port", 8443, "Port for HTTPS, 0 will disable this protocol")
}

// mustGetenv gets env value with default fallback
func mustGetenv(env, defaultValue string) string {
if v := os.Getenv(env); v != "" {
return v
}
return defaultValue
}
84 changes: 84 additions & 0 deletions debugapp/tls.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package debugapp

import (
"bytes"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"io/ioutil"
"log"
"math/big"
"time"
)

// createCert creates a certificate and key in temporary files and returns their paths.
func createCert() (certFilePath string, keyFilepath string) {
cert, key, err := generateInsecureCertAndKey("debugapp", time.Now(), 24*time.Hour*1825)
if err != nil {
log.Fatal(err)
}

tmpCert, err := ioutil.TempFile("", "server.crt")
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(tmpCert.Name(), cert, 0644); err != nil {
log.Fatal(err)
}

tmpKey, err := ioutil.TempFile("", "server.key")
if err != nil {
log.Fatal(err)
}
if err := ioutil.WriteFile(tmpKey.Name(), key, 0644); err != nil {
log.Fatal(err)
}

return tmpCert.Name(), tmpKey.Name()
}

const rsaBits = 2048

// https://golang.org/src/crypto/tls/generate_cert.go
func generateInsecureCertAndKey(organization string, validFrom time.Time, validFor time.Duration) (cert, key []byte, err error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("failed to generate serial number: %s", err)
}

validUntill := validFrom.Add(validFor)

priv, err := rsa.GenerateKey(rand.Reader, rsaBits)
if err != nil {
log.Fatalf("failed to generate private key: %s", err)
}

template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{organization},
},
NotBefore: validFrom,
NotAfter: validUntill,

KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}

derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
if err != nil {
log.Fatalf("Failed to create certificate: %s", err)
}
var certBytes bytes.Buffer
pem.Encode(&certBytes, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})

var keyBytes bytes.Buffer
pb := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}
pem.Encode(&keyBytes, pb)

return certBytes.Bytes(), keyBytes.Bytes(), nil
}
8 changes: 5 additions & 3 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ cat <<-EOF >>~/.bashrc
echo "|____/ \\\\___|_.__/ \\\\__,_|\\\\__, /_/ \\\\_\\\\ .__/| .__/ "
echo " |___/ |_| |_| "
echo " "
echo "Welcome to DebugApp Testing Centre"
echo "Welcome to DebugApp!"
echo ""
echo "Simple HTTP server is listening on the port you specified (default: 80)"
echo "Simple HTTP and HTTPS server are served for debugging purposes"
echo ""
EOF

exec /bin/debugapp -port ${DEBUGAPP_PORT:-80}
exec /bin/debugapp \
--http-port ${DEBUGAPP_HTTP_PORT:-80} \
--https-port ${DEBUGAPP_HTTPS_PORT:-443}
4 changes: 0 additions & 4 deletions k8s/debugapp.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
#
# If you only want a single pod
#

---
apiVersion: v1
kind: Pod
Expand Down
15 changes: 7 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
package main

import (
"context"
"flag"
"fmt"
"net/http"
"log"

"github.com/williamchanrico/debugapp/debugapp"
)

func main() {
port := flag.String("port", "80", "Port to listen on")
debugapp.RegisterFlags()
flag.Parse()

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Welcome to DebugApp!\n")
})

http.ListenAndServe("0.0.0.0:"+*port, nil)
log.Println("starting debugapp server!")
debugapp.RunHTTPServer(context.Background())
}

0 comments on commit 0daf6eb

Please sign in to comment.