This repository has been archived by the owner on Oct 28, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
156 lines (137 loc) · 4.47 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"flag"
"fmt"
"os"
"os/signal"
"runtime/pprof"
"strings"
"syscall"
"github.com/apex/log"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/joho/godotenv"
"github.com/script-development/RT-CV/controller"
"github.com/script-development/RT-CV/db"
"github.com/script-development/RT-CV/db/mongo"
"github.com/script-development/RT-CV/db/mongo/backup"
"github.com/script-development/RT-CV/helpers/random"
"github.com/script-development/RT-CV/helpers/requestLogger"
"github.com/script-development/RT-CV/helpers/slack"
"github.com/script-development/RT-CV/mock"
"github.com/script-development/RT-CV/models"
"github.com/script-development/RT-CV/models/matcher"
)
// AppVersion is used for the X-App-Version header and in the /health route
// This variable can be set by:
//
// go build -ldflags "-X main.AppVersion=1.0.0"
var AppVersion = "LOCAL"
func main() {
doProfile := false
forceBackup := false
restoreBackup := ""
flag.BoolVar(&doProfile, "profile", false, "start profiling")
flag.BoolVar(&forceBackup, "forceBackup", false, "force a creating a backup")
flag.StringVar(&restoreBackup, "restoreBackup", "", "select a backup file to restore into the database")
flag.Parse()
if restoreBackup == "" {
restoreBackup = os.Getenv("RESTORE_BACKUP")
}
// Seed the random package so generated values are "actually" random
random.Seed()
if doProfile {
f, err := os.Create("cpu.profile")
if err != nil {
log.WithField("error", err).Fatal("could not create cpu profile")
}
err = pprof.StartCPUProfile(f)
if err != nil {
log.WithField("error", err).Fatal("could not start CPU profile")
}
exitSignal := make(chan os.Signal, 1)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-exitSignal
pprof.StopCPUProfile()
_ = f.Close()
fmt.Println("saved cpu profile to cpu.profile")
fmt.Println("the profile can be inspected using: go tool pprof -http localhost:3333 cpu.profile")
os.Exit(0)
}()
}
// Loading the .env if available
_, err := os.Stat(".env")
if err == nil {
err := godotenv.Load()
if err != nil {
log.Fatalf("Error loading .env file: %s", err.Error())
}
} else {
log.Info("No .env file found")
}
slackWebHookURL := strings.TrimSpace(os.Getenv("SLACK_WEBHOOK_URL"))
if slackWebHookURL != "" {
slack.SetupLogHandler(slackWebHookURL)
}
// Initialize the database
var dbConn db.Connection
useTestingDB := strings.ToLower(os.Getenv("USE_TESTING_DB")) == "true"
if useTestingDB {
dbConn = mock.NewMockDB()
log.WithField("id", mock.DashboardKey.ID.Hex()).WithField("key", mock.DashboardKey.Key).Info("Mock dashboard key")
if restoreBackup != "" {
log.Fatal("Restoring a backup is not supported in the testing database")
}
} else {
dbConn = mongo.ConnectToDB()
if restoreBackup != "" {
backup.Restore(dbConn, restoreBackup, backup.StartScheduleOptionsFromEnv())
os.Exit(0)
}
}
dbConn.RegisterEntries(
&models.APIKey{},
&models.Profile{},
&models.Backup{},
&models.OnMatchHook{},
&matcher.Branch{},
&models.ScraperLoginUsers{},
)
backupEnabled := strings.ToLower(os.Getenv("MONGODB_BACKUP_ENABLED")) == "true"
if backupEnabled {
if useTestingDB {
log.Warn("Backup is not supported in testing mode")
} else {
backup.StartsSchedule(dbConn, backup.StartScheduleOptionsFromEnv(), forceBackup)
}
}
models.CheckDashboardKeyExists(dbConn)
// Create a new fiber instance (http server)
// do not use fiber Prefork!, this service is not written to support it
app := fiber.New(fiber.Config{
ErrorHandler: controller.FiberErrorHandler,
// We need this as without it API keys are sometimes overwritten while the request is still running.
// This causes very wired behavior like matching a cv from one scraper with another scraper's key because 2 scrapers send the cv on the exact same time :/
Immutable: true,
})
app.Use(recover.New())
app.Use(cors.New())
app.Use(func(c *fiber.Ctx) error {
err = c.Next()
c.Set("X-App-Version", AppVersion)
return err
})
app.Use(controller.InsertData(dbConn))
app.Use(requestLogger.New())
// Setup the app routes
controller.Routes(app, AppVersion, false)
testingDieAfterInit := os.Getenv("TESTING_DIE_AFTER_INIT")
if testingDieAfterInit == "true" || testingDieAfterInit == "TRUE" {
// Used in the CD/CI to test if the application can startup without problems
return
}
// Start the webserver
log.Fatal(app.Listen(":4000").Error())
}