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

Finish inital schema migration script

This commit is contained in:
Lee Brown
2019-05-23 14:01:24 -05:00
parent 790c7b3255
commit 271bf37c5d
16 changed files with 749 additions and 288 deletions

View File

@ -30,9 +30,12 @@ import (
"github.com/aws/aws-sdk-go/aws/session"
"github.com/go-redis/redis"
"github.com/kelseyhightower/envconfig"
"github.com/lib/pq"
"go.opencensus.io/trace"
awstrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/aws/aws-sdk-go/aws"
sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql"
redistrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/go-redis/redis"
sqlxtrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/jmoiron/sqlx"
)
// build is the git version of this program. It is set using build flags in the makefile.
@ -74,6 +77,41 @@ func main() {
DebugHost string `default:"0.0.0.0:4000" envconfig:"APP_DEBUG_HOST"`
ShutdownTimeout time.Duration `default:"5s" envconfig:"APP_SHUTDOWN_TIMEOUT"`
}
Redis struct {
DialTimeout time.Duration `default:"5s" envconfig:"REDIS_DIAL_TIMEOUT"`
Host string `default:":6379" envconfig:"REDIS_HOST"`
DB int `default:"1" envconfig:"REDIS_DB"`
MaxmemoryPolicy string `envconfig:"REDIS_MAXMEMORY_POLICY"`
}
DB struct {
Host string `default:"127.0.0.1:5433" envconfig:"DB_HOST"`
User string `default:"postgres" envconfig:"DB_USER"`
Pass string `default:"postgres" envconfig:"DB_PASS" json:"-"` // don't print
Database string `default:"shared" envconfig:"DB_DATABASE"`
Driver string `default:"postgres" envconfig:"DB_DRIVER"`
Timezone string `default:"utc" envconfig:"DB_TIMEZONE"`
DisableTLS bool `default:"false" envconfig:"DB_DISABLE_TLS"`
}
Trace struct {
Host string `default:"http://tracer:3002/v1/publish" envconfig:"TRACE_HOST"`
BatchSize int `default:"1000" envconfig:"TRACE_BATCH_SIZE"`
SendInterval time.Duration `default:"15s" envconfig:"TRACE_SEND_INTERVAL"`
SendTimeout time.Duration `default:"500ms" envconfig:"TRACE_SEND_TIMEOUT"`
}
AwsAccount struct {
AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID"`
SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY" json:"-"` // don't print
Region string `default:"us-east-1" envconfig:"AWS_REGION"`
// Get an AWS session from an implicit source if no explicit
// configuration is provided. This is useful for taking advantage of
// EC2/ECS instance roles.
UseRole bool `envconfig:"AWS_USE_ROLE"`
}
Auth struct {
AwsSecretID string `default:"auth-secret-key" envconfig:"AUTH_AWS_SECRET_ID"`
KeyExpiration time.Duration `default:"3600s" envconfig:"AUTH_KEY_EXPIRATION"`
}
BuildInfo struct {
CiCommitRefName string `envconfig:"CI_COMMIT_REF_NAME"`
CiCommitRefSlug string `envconfig:"CI_COMMIT_REF_SLUG"`
@ -86,42 +124,15 @@ func main() {
CiPipelineId string `envconfig:"CI_COMMIT_PIPELINE_ID"`
CiPipelineUrl string `envconfig:"CI_COMMIT_PIPELINE_URL"`
}
Redis struct {
DialTimeout time.Duration `default:"5s" envconfig:"REDIS_DIAL_TIMEOUT"`
Host string `default:":6379" envconfig:"REDIS_HOST"`
DB int `default:"1" envconfig:"REDIS_DB"`
MaxmemoryPolicy string `envconfig:"REDIS_MAXMEMORY_POLICY"`
}
DB struct {
DialTimeout time.Duration `default:"5s" envconfig:"DB_DIAL_TIMEOUT"`
Host string `default:"mongo:27017/gotraining" envconfig:"DB_HOST"`
}
Trace struct {
Host string `default:"http://tracer:3002/v1/publish" envconfig:"TRACE_HOST"`
BatchSize int `default:"1000" envconfig:"TRACE_BATCH_SIZE"`
SendInterval time.Duration `default:"15s" envconfig:"TRACE_SEND_INTERVAL"`
SendTimeout time.Duration `default:"500ms" envconfig:"TRACE_SEND_TIMEOUT"`
}
AwsAccount struct {
AccessKeyID string `envconfig:"AWS_ACCESS_KEY_ID"`
SecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY"`
Region string `default:"us-east-1" envconfig:"AWS_REGION"`
// Get an AWS session from an implicit source if no explicit
// configuration is provided. This is useful for taking advantage of
// EC2/ECS instance roles.
UseRole bool `envconfig:"AWS_USE_ROLE"`
}
Auth struct {
AwsSecretID string `default:"auth-secret-key" envconfig:"AUTH_AWS_SECRET_ID"`
KeyExpiration time.Duration `default:"3600s" envconfig:"AUTH_KEY_EXPIRATION"`
}
CMD string `envconfig:"CMD"`
}
// !!! This prefix seems buried, if you copy and paste this main.go
// file, its likely you will forget to update this.
if err := envconfig.Process("WEB_APP", &cfg); err != nil {
// The prefix used for loading env variables.
// ie: export WEB_APP_ENV=dev
envKeyPrefix := "WEB_APP"
// For additional details refer to https://github.com/kelseyhightower/envconfig
if err := envconfig.Process(envKeyPrefix, &cfg); err != nil {
log.Fatalf("main : Parsing Config : %v", err)
}
@ -132,6 +143,9 @@ func main() {
return // We displayed help.
}
// =========================================================================
// Config Validation & Defaults
// If base URL is empty, set the default value from the HTTP Host
if cfg.App.BaseUrl == "" {
baseUrl := cfg.HTTP.Host
@ -149,16 +163,22 @@ func main() {
}
// =========================================================================
// App Starting
// Log App Info
// Print the build version for our logs. Also expose it under /debug/vars.
expvar.NewString("build").Set(build)
log.Printf("main : Started : Application Initializing version %q", build)
defer log.Println("main : Completed")
cfgJSON, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
log.Fatalf("main : Marshalling Config to JSON : %v", err)
// Print the config for our logs. It's important to any credentials in the config
// that could expose a security risk are excluded from being json encoded by
// applying the tag `json:"-"` to the struct var.
{
cfgJSON, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
log.Fatalf("main : Marshalling Config to JSON : %v", err)
}
log.Printf("main : Config : %v\n", string(cfgJSON))
}
// TODO: Validate what is being written to the logs. We don't
@ -199,7 +219,7 @@ func main() {
// if the maxmemory policy is set for redis, make sure its set on the cluster
// default not set and will based on the redis config values defined on the server
if cfg.Redis.MaxmemoryPolicy != "" {
err = redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err()
err := redisClient.ConfigSet(evictPolicyConfigKey, cfg.Redis.MaxmemoryPolicy).Err()
if err != nil {
log.Fatalf("main : redis : ConfigSet maxmemory-policy : %v", err)
}
@ -214,6 +234,42 @@ func main() {
}
}
// =========================================================================
// Start Database
var dbUrl url.URL
{
// Query parameters.
var q url.Values
// Handle SSL Mode
if cfg.DB.DisableTLS {
q.Set("sslmode", "disable")
} else {
q.Set("sslmode", "require")
}
q.Set("timezone", cfg.DB.Timezone)
// Construct url.
dbUrl = url.URL{
Scheme: cfg.DB.Driver,
User: url.UserPassword(cfg.DB.User, cfg.DB.Pass),
Host: cfg.DB.Host,
Path: cfg.DB.Database,
RawQuery: q.Encode(),
}
}
// Register informs the sqlxtrace package of the driver that we will be using in our program.
// It uses a default service name, in the below case "postgres.db". To use a custom service
// name use RegisterWithServiceName.
sqltrace.Register(cfg.DB.Driver, &pq.Driver{}, sqltrace.WithServiceName("my-service"))
masterDb, err := sqlxtrace.Open(cfg.DB.Driver, dbUrl.String())
if err != nil {
log.Fatalf("main : Register DB : %s : %v", cfg.DB.Driver, err)
}
defer masterDb.Close()
// =========================================================================
// Deploy
switch cfg.CMD {
@ -494,7 +550,7 @@ func main() {
api := http.Server{
Addr: cfg.HTTP.Host,
Handler: handlers.APP(shutdown, log, cfg.App.StaticDir, cfg.App.TemplateDir, nil, nil, renderer),
Handler: handlers.APP(shutdown, log, cfg.App.StaticDir, cfg.App.TemplateDir, masterDb, nil, renderer),
ReadTimeout: cfg.HTTP.ReadTimeout,
WriteTimeout: cfg.HTTP.WriteTimeout,
MaxHeaderBytes: 1 << 20,