-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b254a99
Showing
26 changed files
with
2,034 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Dockerfile | ||
|
||
# Application output | ||
hbaas-server | ||
|
||
# Auto-generated Swagger docs | ||
docs | ||
|
||
# Generated files | ||
gen-*.go | ||
|
||
# Binary data generated with go-bindata | ||
bindata.go | ||
|
||
.env | ||
.go-pkg | ||
.go-bin | ||
|
||
.idea | ||
.vscode | ||
|
||
*.swp | ||
*.swo | ||
.*.swp | ||
.*.swo | ||
*~ | ||
.*~ | ||
|
||
.git | ||
.gitignore | ||
.dockerignore | ||
.env.example | ||
.gitlab-ci.yml |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
HBAAS_POSTGRES_URL="postgres://{ps_user}:{ps_password}@localhost:5432/{ps_database}?sslmode=disable" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Application output | ||
hbaas-server | ||
|
||
# Excel spreadsheet for creating the seed people data. | ||
seed-data.xlsx | ||
|
||
# Generated files | ||
gen-*.go | ||
|
||
# Auto-generated Swagger docs | ||
docs | ||
|
||
# Binary data generated with go-bindata | ||
bindata.go | ||
|
||
.env | ||
.go-pkg | ||
.go-bin | ||
|
||
# IDE files | ||
.idea | ||
.vscode | ||
|
||
# Vim files | ||
*.swp | ||
*.swo | ||
.*.swp | ||
.*.swo | ||
*~ | ||
.*~ |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
image: golang | ||
|
||
cache: | ||
key: ${CI_COMMIT_REF_SLUG} | ||
paths: | ||
- .go-bin | ||
- .go-pkg | ||
|
||
stages: | ||
- build | ||
- lint | ||
# No testing implemented currently. | ||
|
||
build-code: | ||
stage: build | ||
script: | ||
- make compile | ||
|
||
lint: | ||
stage: lint | ||
before_script: | ||
- wget -O - -q https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /go/bin v1.21.0 | ||
- make install | ||
# We need to run the code-gen scripts for the linting to work. | ||
- make code-gen | ||
script: | ||
- golangci-lint run . |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Builder stage | ||
FROM golang AS builder | ||
|
||
ENV GO111MODULE=on | ||
|
||
ARG version | ||
ARG build | ||
|
||
ENV VERSION=$version | ||
ENV BUILD=$build | ||
ENV OUTBINDIR=/app | ||
|
||
WORKDIR /app | ||
|
||
# Enable Docker cache for go modules. | ||
COPY go.mod . | ||
COPY go.sum . | ||
RUN GOPATH=/app/.go-pkg:/app GOBIN=/app/.go-bin go mod download | ||
|
||
COPY Makefile . | ||
RUN make install | ||
|
||
COPY . . | ||
|
||
RUN make compile-linux | ||
|
||
# Runner stage | ||
FROM scratch | ||
# If we need the config.toml in the future that'll need to be copied over too. | ||
COPY --from=builder /app/hbaas-server /app/ | ||
|
||
# Document that the service listens on port 8080. | ||
EXPOSE 8000 | ||
EXPOSE 4443 | ||
|
||
# Run the outyet command by default when the container starts. | ||
CMD ["/app/hbaas-server", "run-server"] |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
-include .env | ||
|
||
SHELL := /bin/bash | ||
|
||
PROJECTNAME := hbaas-server | ||
|
||
VERSION?=$(shell git describe --tags --always) | ||
BUILDTIME=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ") | ||
|
||
# Go related variables. | ||
GOBASE := $(shell pwd) | ||
GOPATH := $(GOBASE)/.go-pkg:$(GOBASE) | ||
GOBIN := $(GOBASE)/.go-bin | ||
GOFILES := $(wildcard *.go) | ||
|
||
# Directory in which to put the output executable. | ||
OUTBINDIR?=$(GOBASE) | ||
|
||
PACKAGENAME=$(shell go list) | ||
|
||
# Use linker flags to provide version/build settings | ||
LDFLAGS=-ldflags "-X '$(PACKAGENAME)/version.Version=$(VERSION)' -X '$(PACKAGENAME)/version.BuildTime=$(BUILDTIME)'" | ||
|
||
LINUXBUILD=CGO_ENABLED=0 GOOS=linux GOARCH=amd64 | ||
|
||
# Make is verbose in Linux. Make it silent. | ||
MAKEFLAGS += --silent | ||
|
||
IS_INTERACTIVE:=$(shell [ -t 0 ] && echo 1) | ||
|
||
ifdef IS_INTERACTIVE | ||
LOG_INFO := $(shell tput setaf 12) | ||
LOG_ERROR := $(shell tput setaf 9) | ||
LOG_END := $(shell tput sgr0) | ||
endif | ||
|
||
define log | ||
echo -e "$(LOG_INFO)⇛ $(1)$(LOG_END)" | ||
endef | ||
|
||
define log-error | ||
echo -e "$(LOG_ERROR)⇛ $(1)$(LOG_END)" | ||
endef | ||
|
||
default: help | ||
|
||
## install: Install missing dependencies. Runs `go get` internally. e.g; make install get=github.com/foo/bar | ||
install: go-get-build-deps go-mod-download | ||
|
||
## start: Start in development mode. Auto-starts when code changes. | ||
start: clean compile start-server | ||
|
||
start-server: | ||
@test -e $(OUTBINDIR)/$(PROJECTNAME) || (\ | ||
$(call log-error,Unable to find $(PROJECTNAME) executable.) \ | ||
&& false\ | ||
) | ||
@$(call log,Starting $(PROJECTNAME)...) | ||
@-$(OUTBINDIR)/$(PROJECTNAME) run-server | ||
|
||
## run: Run server with specified args, e.g. `make run args=version` | ||
run: | ||
@$(OUTBINDIR)/$(PROJECTNAME) $(args) | ||
|
||
## compile: Compile the binary. | ||
compile: go-get-build-deps go-mod-download code-gen go-build | ||
|
||
## compile-linux: Compile the binary for Linux. | ||
compile-linux: go-get-build-deps go-mod-download code-gen go-build-linux | ||
|
||
## exec: Run given command, wrapped with custom GOPATH. e.g; make exec run="go test ./..." | ||
exec: | ||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) $(run) | ||
|
||
## build-image: Build Docker image for project. | ||
build-image: | ||
@$(call log,Building Docker image...) | ||
docker build \ | ||
--build-arg version=$(VERSION) \ | ||
--build-arg build=$(BUILD) \ | ||
-t $(PROJECTNAME):latest . || \ | ||
(\ | ||
$(call log-error,Unable to build Docker image.) \ | ||
&& false \ | ||
) | ||
|
||
## clean: Clean build files. Runs `go clean` internally. | ||
clean: | ||
@-rm $(OUTBINDIR)/$(PROJECTNAME) 2> /dev/null | ||
@-$(MAKE) go-clean | ||
@-rm ./**/bindata.go 2> /dev/null | ||
@-rm ./**/gen-*.go 2> /dev/null | ||
|
||
code-gen: | ||
@$(call log,Running pre-build code generation...) | ||
@cd migrations && $(GOBIN)/go-bindata -pkg migrations . || (\ | ||
$(call log-error,Unable to generate binary migration data.) \ | ||
&& false \ | ||
) | ||
@cd seeddata && $(GOBIN)/go-bindata -pkg seeddata . || (\ | ||
$(call log-error,Unable to generate binary database seed data.) \ | ||
&& false \ | ||
) | ||
# If there's no docs package, the docs generation fails. Because of this | ||
# bug, we need to put a stub package in so that Swag can replace it. | ||
@mkdir -p docs | ||
@echo "package docs" > docs/docs.go | ||
@$(GOBIN)/swag init --parseDependency || (\ | ||
$(call log-error,Unable to generate Swagger docs.) \ | ||
&& false \ | ||
) | ||
|
||
go-build: | ||
@$(call log,Building binary...) | ||
|
||
# Uncomment line below for debugging build arguments. | ||
#@echo Building $(PROJECTNAME): GOPATH=$(GOPATH) GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(OUTBINDIR)/$(PROJECTNAME) $(GOFILES) | ||
|
||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go build $(LDFLAGS) -o $(OUTBINDIR)/$(PROJECTNAME) $(GOFILES) || (\ | ||
$(call log-error,Failed to build $(PROJECTNAME).) \ | ||
&& false \ | ||
) | ||
|
||
go-build-linux: | ||
@$(call log,Building binary...) | ||
|
||
# Uncomment line below for debugging build arguments. | ||
#@echo Linux build command: "GOPATH=$(GOPATH) GOBIN=$(GOBIN) $(LINUXBUILD) go build $(LDFLAGS) -o $(OUTBINDIR)/$(PROJECTNAME) $(GOFILES)" | ||
|
||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) $(LINUXBUILD) go build $(LDFLAGS) -o $(OUTBINDIR)/$(PROJECTNAME) $(GOFILES) || (\ | ||
$(call log-error,Failed to build $(PROJECTNAME).) \ | ||
&& false \ | ||
) | ||
|
||
go-generate: | ||
@$(call log,Generating dependency files...) | ||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go generate $(generate) | ||
|
||
go-get-build-deps: | ||
@$(call log,Checking if there are any missing build-time dependencies...) | ||
@make go-get bin=go-bindata pkg=github.com/kevinburke/go-bindata/... | ||
@make go-get bin=swag pkg=github.com/swaggo/swag/cmd/swag | ||
|
||
go-get: | ||
@test -e $(GOBIN)/$(bin) || \ | ||
GOPATH=$(GOPATH) GOBIN=$(GOBIN) go get $(pkg) | ||
|
||
go-mod-download: | ||
@$(call log,Checking if there are any missing modules...) | ||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go mod download | ||
|
||
go-install: | ||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go install $(GOFILES) | ||
|
||
go-clean: | ||
@$(call log,Cleaning build cache) | ||
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go clean | ||
|
||
.PHONY: help | ||
all: help | ||
help: Makefile | ||
@echo | ||
@echo "Choose a command run in "$(PROJECTNAME)":" | ||
@echo | ||
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /' | ||
@echo |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# HBaaS Server | ||
|
||
This is a fun demo API for saying happy birthday to people for the purposes of demonstrating server containerisation and deployment. | ||
|
||
## Software Stack | ||
|
||
This project uses the [Go programming language](https://go.dev/) for rapid prototype development and easy containerisation. | ||
|
||
For the RESTful API, we are using the [Echo](https://echo.labstack.com/) framework due to its ease-of-use, minimalism, extensability but also performance. | ||
|
||
For persistence, GORM is used to interact with a PostgreSQL database. | ||
|
||
## Running | ||
|
||
There are multiple commands available to the application for seeding the database with test values, auto-migrating the database schema and running the main server. | ||
|
||
The main command for the server is: | ||
|
||
```sh | ||
./hbaas-server run-server | ||
``` | ||
|
||
For information on all command-line options, run: | ||
|
||
```sh | ||
./hbaas-server --help | ||
``` | ||
|
||
In order to connect to your local PostgreSQL database, you must specify the `POSTGRES_URL` environment variable. See the `.env.example` file for what this should look like. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package cmd | ||
|
||
import ( | ||
"github.com/drewsilcock/hbaas-server/migrations" | ||
"github.com/golang-migrate/migrate/v4" | ||
bindata "github.com/golang-migrate/migrate/v4/source/go_bindata" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"log" | ||
) | ||
|
||
func init() { | ||
rootCmd.AddCommand(autoMigrateCmd) | ||
} | ||
|
||
var autoMigrateCmd = &cobra.Command{ | ||
Use: "auto-migrate", | ||
Short: "Migrate DB schema", | ||
Long: "Automatically migrate database schema to the latest version.", | ||
Run: autoMigrate, | ||
} | ||
|
||
func autoMigrate(cmd *cobra.Command, args []string) { | ||
assetSource := bindata.Resource(migrations.AssetNames(), | ||
func(name string) ([]byte, error) { | ||
return migrations.Asset(name) | ||
}) | ||
migrationData, err := bindata.WithInstance(assetSource) | ||
if err != nil { | ||
log.Fatal("Unable to read migration data:", err) | ||
} | ||
migrator, err := migrate.NewWithSourceInstance( | ||
"go-bindata", | ||
migrationData, | ||
viper.GetString("POSTGRES_URL"), | ||
) | ||
if err != nil { | ||
log.Fatal("Unable to read create migrator:", err) | ||
} | ||
currentVersion, isDirty, err := migrator.Version() | ||
if err == migrate.ErrNilVersion { | ||
log.Println("No migrations currently applied.") | ||
} else if err != nil { | ||
log.Fatal("Unable to get migration status:", err) | ||
} else { | ||
var status string | ||
if isDirty { | ||
status = "dirty" | ||
} else { | ||
status = "clean" | ||
} | ||
log.Println("Currently", status, "on version", currentVersion) | ||
} | ||
log.Println("Migrating database up to latest...") | ||
if err := migrator.Up(); err != nil { | ||
log.Fatal("Unable to perform 'up' migrations:", err) | ||
} | ||
log.Println("Done") | ||
} |
Oops, something went wrong.