1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-15 00:15:15 +02:00

completed schema migration

This commit is contained in:
Lee Brown
2019-05-25 08:26:37 -05:00
parent c19f46e07f
commit 82cd108ed6
21 changed files with 136 additions and 48 deletions

View File

@ -1,23 +1,8 @@
# Ultimate Service # SaaS Service
Copyright 2018, Ardan Labs Copyright 2019, Geeks Accelerator
info@ardanlabs.com accelerator@geeksinthewoods.com.com
## Licensing
```
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
## Description ## Description
@ -107,11 +92,6 @@ Running `make down` will properly stop and terminate the Docker Compose session.
The service provides record keeping for someone running a multi-family garage sale. Authenticated users can maintain a list of projects for sale. The service provides record keeping for someone running a multi-family garage sale. Authenticated users can maintain a list of projects for sale.
<!--The service uses the following models:-->
<!--<img src="https://raw.githubusercontent.com/ardanlabs/service/master/models.jpg" alt="Garage Sale Service Models" title="Garage Sale Service Models" />-->
<!--(Diagram generated with draw.io using `models.xml` file)-->
### Making Requests ### Making Requests

View File

@ -37,7 +37,7 @@ COPY --from=builder /gosrv /
#COPY --from=builder /static /static #COPY --from=builder /static /static
COPY --from=builder /templates /templates COPY --from=builder /templates /templates
ARG gogc="50" ARG gogc="20"
ENV GOGC $gogc ENV GOGC $gogc
ENTRYPOINT ["/gosrv"] ENTRYPOINT ["/gosrv"]

View File

@ -78,12 +78,12 @@ func main() {
DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"` DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"`
} }
Trace struct { Trace struct {
Host string `default:"127.0.0.1" envconfig:"DD_TRACE_AGENT_HOSTNAME"` Host string `default:"127.0.0.1" envconfig:"DD_TRACE_AGENT_HOSTNAME"`
Port int `default:"8126" envconfig:"DD_TRACE_AGENT_PORT"` Port int `default:"8126" envconfig:"DD_TRACE_AGENT_PORT"`
AnalyticsRate float64 `default:"0.10" envconfig:"ANALYTICS_RATE"` AnalyticsRate float64 `default:"0.10" envconfig:"ANALYTICS_RATE"`
} }
Aws struct { Aws struct {
AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID" required:"true"` // WEB_API_AWS_AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY_ID AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID" required:"true"` // WEB_API_AWS_AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY_ID
SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY" required:"true" json:"-"` // don't print SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY" required:"true" json:"-"` // don't print
Region string `default:"us-east-1" envconfig:"AWS_REGION"` Region string `default:"us-east-1" envconfig:"AWS_REGION"`

View File

@ -37,7 +37,7 @@ COPY --from=builder /gosrv /
COPY --from=builder /static /static COPY --from=builder /static /static
COPY --from=builder /templates /templates COPY --from=builder /templates /templates
ARG gogc="50" ARG gogc="20"
ENV GOGC $gogc ENV GOGC $gogc
ENTRYPOINT ["/gosrv"] ENTRYPOINT ["/gosrv"]

View File

@ -92,12 +92,12 @@ func main() {
DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"` DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"`
} }
Trace struct { Trace struct {
Host string `default:"127.0.0.1" envconfig:"DD_TRACE_AGENT_HOSTNAME"` Host string `default:"127.0.0.1" envconfig:"DD_TRACE_AGENT_HOSTNAME"`
Port int `default:"8126" envconfig:"DD_TRACE_AGENT_PORT"` Port int `default:"8126" envconfig:"DD_TRACE_AGENT_PORT"`
AnalyticsRate float64 `default:"0.10" envconfig:"ANALYTICS_RATE"` AnalyticsRate float64 `default:"0.10" envconfig:"ANALYTICS_RATE"`
} }
Aws struct { Aws struct {
AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID" required:"true"` // WEB_API_AWS_AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY_ID AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID" required:"true"` // WEB_API_AWS_AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY_ID
SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY" required:"true" json:"-"` // don't print SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY" required:"true" json:"-"` // don't print
Region string `default:"us-east-1" envconfig:"AWS_REGION"` Region string `default:"us-east-1" envconfig:"AWS_REGION"`

View File

@ -11,6 +11,9 @@ ENV SERVICE_NAME $service
ARG env="dev" ARG env="dev"
ENV ENV $env ENV ENV $env
ARG gogc="10"
ENV GOGC $gogc
ENV DD_TAGS="source:docker service:${service} service_name:${service} cluster:NA env:${ENV}" ENV DD_TAGS="source:docker service:${service} service_name:${service} cluster:NA env:${ENV}"
CMD ["/custom-init.sh"] CMD ["/custom-init.sh"]

View File

@ -6,7 +6,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dimfeld/httptreemux v5.0.1+incompatible github.com/dimfeld/httptreemux v5.0.1+incompatible
github.com/gitwak/gondolier v0.0.0-20190521205431-504d297a6c42 // indirect github.com/gitwak/gondolier v0.0.0-20190521205431-504d297a6c42 // indirect
github.com/gitwak/sqlxmigrate v0.0.0-20190522211042-9625063dea5d github.com/gitwak/sqlxmigrate v0.0.0-20190525131054-1f06ba9f0748
github.com/go-playground/locales v0.12.1 github.com/go-playground/locales v0.12.1
github.com/go-playground/universal-translator v0.16.0 github.com/go-playground/universal-translator v0.16.0
github.com/go-redis/redis v6.15.2+incompatible github.com/go-redis/redis v6.15.2+incompatible

View File

@ -14,6 +14,10 @@ github.com/gitwak/gondolier v0.0.0-20190521205431-504d297a6c42 h1:+lo4HFeG6Llcgw
github.com/gitwak/gondolier v0.0.0-20190521205431-504d297a6c42/go.mod h1:ecEQ8e4eHeWKPf+g6ByatPM7l4QZgR3G5ZIZKvEAdCE= github.com/gitwak/gondolier v0.0.0-20190521205431-504d297a6c42/go.mod h1:ecEQ8e4eHeWKPf+g6ByatPM7l4QZgR3G5ZIZKvEAdCE=
github.com/gitwak/sqlxmigrate v0.0.0-20190522211042-9625063dea5d h1:oaUPMY0F+lNUkyB5tzsQS3EC0m9Cxdglesp63i3UPso= github.com/gitwak/sqlxmigrate v0.0.0-20190522211042-9625063dea5d h1:oaUPMY0F+lNUkyB5tzsQS3EC0m9Cxdglesp63i3UPso=
github.com/gitwak/sqlxmigrate v0.0.0-20190522211042-9625063dea5d/go.mod h1:e7vYkZWKUHC2Vl0/dIiQRKR3z2HMuswoLf2IiQmnMoQ= github.com/gitwak/sqlxmigrate v0.0.0-20190522211042-9625063dea5d/go.mod h1:e7vYkZWKUHC2Vl0/dIiQRKR3z2HMuswoLf2IiQmnMoQ=
github.com/gitwak/sqlxmigrate v0.0.0-20190525050002-e22c656832a9 h1:se8XE/N8ZWACgA/p86OPlE56AOuguWcS1E6eUCWP93I=
github.com/gitwak/sqlxmigrate v0.0.0-20190525050002-e22c656832a9/go.mod h1:e7vYkZWKUHC2Vl0/dIiQRKR3z2HMuswoLf2IiQmnMoQ=
github.com/gitwak/sqlxmigrate v0.0.0-20190525131054-1f06ba9f0748 h1:ln68Q5KHq1hCO2yxOek7ejF0ijfhRkWJqI5D5jjWF3g=
github.com/gitwak/sqlxmigrate v0.0.0-20190525131054-1f06ba9f0748/go.mod h1:e7vYkZWKUHC2Vl0/dIiQRKR3z2HMuswoLf2IiQmnMoQ=
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc= github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM= github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=

View File

@ -5,10 +5,10 @@ import (
"net/http" "net/http"
"strings" "strings"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/auth"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
"github.com/pkg/errors" "github.com/pkg/errors"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
// ErrForbidden is returned when an authenticated user does not have a // ErrForbidden is returned when an authenticated user does not have a

View File

@ -5,8 +5,8 @@ import (
"log" "log"
"net/http" "net/http"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
// Errors handles errors coming out of the call chain. It detects normal // Errors handles errors coming out of the call chain. It detects normal

View File

@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"time" "time"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
// Logger writes some information about the request to the logs in the // Logger writes some information about the request to the logs in the

View File

@ -6,8 +6,8 @@ import (
"net/http" "net/http"
"runtime" "runtime"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
// m contains the global program counters for the application. // m contains the global program counters for the application.

View File

@ -5,9 +5,9 @@ import (
"net/http" "net/http"
"runtime/debug" "runtime/debug"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
"github.com/pkg/errors" "github.com/pkg/errors"
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
) )
// Panics recovers from panics and converts the panic to an error so it is // Panics recovers from panics and converts the panic to an error so it is

View File

@ -41,6 +41,8 @@ func Trace() web.Middleware {
if !ok { if !ok {
return web.NewShutdownError("web value missing from context") return web.NewShutdownError("web value missing from context")
} }
v.TraceID = span.Context().TraceID()
v.SpanID = span.Context().SpanID()
// Execute the request handler // Execute the request handler
err := before(ctx, w, r, params) err := before(ctx, w, r, params)

View File

@ -0,0 +1,19 @@
package logger
import (
"context"
"fmt"
"geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/web"
)
// WithContext manual injects context values to log message including Trace ID
func WithContext(ctx context.Context, msg string) string {
v, ok := ctx.Value(web.KeyValues).(*web.Values)
if !ok {
return msg
}
cm := fmt.Sprintf("dd.trace_id=%d dd.span_id=%d", v.TraceID, v.SpanID)
return cm + ": " + msg
}

View File

@ -20,6 +20,8 @@ const KeyValues ctxKey = 1
// Values represent state for each request. // Values represent state for each request.
type Values struct { type Values struct {
Now time.Time Now time.Time
TraceID uint64
SpanID uint64
StatusCode int StatusCode int
} }
@ -71,7 +73,7 @@ func (a *App) Handle(verb, path string, handler Handler, mw ...Middleware) {
// Set the context with the required values to // Set the context with the required values to
// process the request. // process the request.
v := Values{ v := Values{
Now: time.Now(), Now: time.Now(),
} }
ctx := context.WithValue(r.Context(), KeyValues, &v) ctx := context.WithValue(r.Context(), KeyValues, &v)

1
example-project/schema/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
schema

View File

@ -0,0 +1,68 @@
# SaaS Schema
Copyright 2019, Geeks Accelerator
accelerator@geeksinthewoods.com.com
## Description
Service is handles the schema migration for the project.
## Local Installation
### Build
```bash
go build .
```
### Usage
```bash
./schema -h
Usage of ./schema
--env string <dev>
--db_host string <127.0.0.1:5433>
--db_user string <postgres>
--db_pass string <postgres>
--db_database string <shared>
--db_driver string <postgres>
--db_timezone string <utc>
--db_disabletls bool <false>
```
### Execution
Manually execute binary after build
```bash
./schema
Schema : 2019/05/25 08:20:08.152557 main.go:64: main : Started : Application Initializing version "develop"
Schema : 2019/05/25 08:20:08.152814 main.go:75: main : Config : {
"Env": "dev",
"DB": {
"Host": "127.0.0.1:5433",
"User": "postgres",
"Database": "shared",
"Driver": "postgres",
"Timezone": "utc",
"DisableTLS": true
}
}
Schema : 2019/05/25 08:20:08.158270 sqlxmigrate.go:478: HasTable migrations - SELECT 1 FROM migrations
Schema : 2019/05/25 08:20:08.164275 sqlxmigrate.go:413: Migration SCHEMA_INIT - SELECT count(0) FROM migrations WHERE id = $1
Schema : 2019/05/25 08:20:08.166391 sqlxmigrate.go:368: Migration 20190522-01a - checking
Schema : 2019/05/25 08:20:08.166405 sqlxmigrate.go:413: Migration 20190522-01a - SELECT count(0) FROM migrations WHERE id = $1
Schema : 2019/05/25 08:20:08.168066 sqlxmigrate.go:375: Migration 20190522-01a - already ran
Schema : 2019/05/25 08:20:08.168078 sqlxmigrate.go:368: Migration 20190522-01b - checking
Schema : 2019/05/25 08:20:08.168084 sqlxmigrate.go:413: Migration 20190522-01b - SELECT count(0) FROM migrations WHERE id = $1
Schema : 2019/05/25 08:20:08.170297 sqlxmigrate.go:375: Migration 20190522-01b - already ran
Schema : 2019/05/25 08:20:08.170319 sqlxmigrate.go:368: Migration 20190522-01c - checking
Schema : 2019/05/25 08:20:08.170327 sqlxmigrate.go:413: Migration 20190522-01c - SELECT count(0) FROM migrations WHERE id = $1
Schema : 2019/05/25 08:20:08.172044 sqlxmigrate.go:375: Migration 20190522-01c - already ran
Schema : 2019/05/25 08:20:08.172831 main.go:130: main : Migrate : Completed
Schema : 2019/05/25 08:20:08.172935 main.go:131: main : Completed
```
Or alternative use the make file
```bash
make run
```

View File

@ -30,13 +30,13 @@ func main() {
var cfg struct { var cfg struct {
Env string `default:"dev" envconfig:"ENV"` Env string `default:"dev" envconfig:"ENV"`
DB struct { DB struct {
Host string `default:"127.0.0.1:5433" envconfig:"DB_HOST"` Host string `default:"127.0.0.1:5433" envconfig:"HOST"`
User string `default:"postgres" envconfig:"DB_USER"` User string `default:"postgres" envconfig:"USER"`
Pass string `default:"postgres" envconfig:"DB_PASS" json:"-"` // don't print Pass string `default:"postgres" envconfig:"PASS" json:"-"` // don't print
Database string `default:"shared" envconfig:"DB_DATABASE"` Database string `default:"shared" envconfig:"DATABASE"`
Driver string `default:"postgres" envconfig:"DB_DRIVER"` Driver string `default:"postgres" envconfig:"DRIVER"`
Timezone string `default:"utc" envconfig:"DB_TIMEZONE"` Timezone string `default:"utc" envconfig:"TIMEZONE"`
DisableTLS bool `default:"false" envconfig:"DB_DISABLE_TLS"` DisableTLS bool `default:"false" envconfig:"DISABLE_TLS"`
} }
} }
@ -80,7 +80,7 @@ func main() {
var dbUrl url.URL var dbUrl url.URL
{ {
// Query parameters. // Query parameters.
var q url.Values var q url.Values = make(map[string][]string)
// Handle SSL Mode // Handle SSL Mode
if cfg.DB.DisableTLS { if cfg.DB.DisableTLS {
@ -117,6 +117,7 @@ func main() {
// Load list of Schema migrations and init new sqlxmigrate client // Load list of Schema migrations and init new sqlxmigrate client
migrations := migrationList(masterDb, log) migrations := migrationList(masterDb, log)
m := sqlxmigrate.New(masterDb, sqlxmigrate.DefaultOptions, migrations) m := sqlxmigrate.New(masterDb, sqlxmigrate.DefaultOptions, migrations)
m.SetLogger(log)
// Append any schema that need to be applied if this is a fresh migration // Append any schema that need to be applied if this is a fresh migration
// ie. the migrations database table does not exist. // ie. the migrations database table does not exist.

View File

@ -0,0 +1,4 @@
SHELL := /bin/bash
run:
go build . && ./schema

View File

@ -0,0 +1,4 @@
export SCHEMA_DB_HOST=127.0.0.1:5433
export SCHEMA_DB_USER=postgres
export SCHEMA_DB_PASS=postgres
export SCHEMA_DB_DISABLE_TLS=true