From 5ca55b7c942f864011bdba06a202f9620cee2ce6 Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Mon, 7 Oct 2024 14:51:11 +0200 Subject: [PATCH 1/9] feat: logging This commit adds the needed dependencies for our new logging module, zap! It also adds logs/** to our gitignore --- .gitignore | 1 + go.mod | 3 ++- go.sum | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3df6d5a..ffd520f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ config.yaml config.yml packagelock.pid packagelock/** +logs/** diff --git a/go.mod b/go.mod index 1df31b0..8ba75bf 100644 --- a/go.mod +++ b/go.mod @@ -46,7 +46,8 @@ require ( github.com/valyala/fasthttp v1.55.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.9.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/sys v0.24.0 // indirect golang.org/x/text v0.17.0 // indirect diff --git a/go.sum b/go.sum index ae262f3..fb85c3e 100644 --- a/go.sum +++ b/go.sum @@ -112,6 +112,10 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= From 326c97d27d730925430e3dd8abac799e2b96aa78 Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:14:33 +0200 Subject: [PATCH 2/9] feat: logging --- main.go | 94 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 35 deletions(-) diff --git a/main.go b/main.go index dcea5d5..4c8b66a 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "packagelock/certs" "packagelock/config" "packagelock/db" + "packagelock/logger" "packagelock/server" "packagelock/structs" "strconv" @@ -76,15 +77,14 @@ var generateCmd = &cobra.Command{ config.Config.GetString("network.ssl-config.privatekeypath")) if err != nil { fmt.Println("There was an error generating the self signed certs: %w", err) + logger.Logger.Warnf("There was an error generating the self signed certs: %s", err) } case "config": config.CreateDefaultConfig(config.Config) case "admin": err := generateAdmin() if err != nil { - // FIXME: Error Handling - // FIXME: Logging! Because: Invocation of admin creation should be logged! - panic(err) + logger.Logger.Panicf("Failed to generate default admin, got: %s", err) } default: fmt.Println("Invalid argument. Use 'certs' or 'config' or 'admin'.") @@ -111,12 +111,18 @@ func init() { rootCmd.AddCommand(restartCmd) rootCmd.AddCommand(stopCmd) + // Declare the Logger into global logger.Logger + var loggerError error + logger.Logger, loggerError = logger.InitLogger() + if loggerError != nil { + // INFO: Essential APP-Part, so crash out asap + panic(loggerError) + } + initConfig() err := db.InitDB() if err != nil { - // FIXME: error Handling - // FIXME: LOGGING! - panic(err) + logger.Logger.Panicf("Got error from db.InitDB: %s", err) } } @@ -124,8 +130,7 @@ func init() { func generateAdmin() error { adminPw, err := password.Generate(64, 10, 10, false, false) if err != nil { - // FIXME: error Handling - panic(err) + logger.Logger.Panicf("Got error while generating ADmin Password: %s", err) } // Admin Data @@ -142,15 +147,14 @@ func generateAdmin() error { // Insert Admin AdminInsertionData, err := db.DB.Create("user", TemporalAdmin) if err != nil { - panic(err) + logger.Logger.Panicf("Got error while inserting Default Admin into DB: %s", err) } // Unmarshal data var createdUser structs.User err = surrealdb.Unmarshal(AdminInsertionData, &createdUser) if err != nil { - pp.Println(AdminInsertionData) - panic(err) + logger.Logger.Panicf("Got error while querring Default Admin: %s", err) } pp.Println(createdUser.Username) @@ -174,8 +178,7 @@ func initConfig() { config.Config.GetString("network.ssl-config.certificatepath"), config.Config.GetString("network.ssl-config.privatekeypath")) if err != nil { - fmt.Printf("Error creating self-signed certificate: %v\n", err) - os.Exit(1) + logger.Logger.Panicf("Error creating self-signed certificate: %v\n", err) } } } @@ -185,11 +188,13 @@ func startServer() { pid := os.Getpid() err := os.WriteFile("packagelock.pid", []byte(strconv.Itoa(pid)), 0644) if err != nil { - fmt.Printf("Failed to write PID file: %v\n", err) + logger.Logger.Panicf("Failed to write PID file: %v\n", err) return } - fmt.Println(config.Config.AllSettings()) + if config.Config.GetString("general.production") == "false" { + logger.Logger.Debug(config.Config.AllSettings()) + } signal.Notify(quitChan, os.Interrupt, syscall.SIGTERM) @@ -204,19 +209,23 @@ func startServer() { // Start server based on SSL config go func() { if config.Config.GetBool("network.ssl") { - fmt.Printf("Starting Fiber HTTPS server at https://%s...\n", serverAddr) + + logger.Logger.Infof("Starting Fiber HTTPS server at https://%s...\n", serverAddr) + err := server.ListenAndServeTLS( router.Router, config.Config.GetString("network.ssl-config.certificatepath"), config.Config.GetString("network.ssl-config.privatekeypath"), serverAddr) if err != nil { - fmt.Printf("Server error: %s\n", err) + logger.Logger.Panicf("Server error: %s\n", err) } } else { - fmt.Printf("Starting Fiber server at %s...\n", serverAddr) + + logger.Logger.Infof("Starting Fiber server at %s...\n", serverAddr) + if err := router.Router.Listen(serverAddr); err != nil { - fmt.Printf("Server error: %s\n", err) + logger.Logger.Panicf("Server error: %s\n", err) } } }() @@ -224,24 +233,34 @@ func startServer() { // Handle restart or quit signals select { case <-restartChan: + fmt.Println("Restarting Fiber server...") + logger.Logger.Info("Restarting Fiber server...") + _, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := router.Router.Shutdown(); err != nil { - fmt.Printf("Server shutdown failed: %v\n", err) + logger.Logger.Warnf("Server shutdown failed: %v\n", err) } else { + + // TODO: add Reason for restart/Stoping fmt.Println("Server stopped.") + logger.Logger.Info("Server stopped.") } startServer() case <-quitChan: + + // TODO: add Reason fro Stopping fmt.Println("Shutting down Fiber server...") + logger.Logger.Info("Shutting down Fiber server...") _, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := router.Router.Shutdown(); err != nil { - fmt.Printf("Server shutdown failed: %v\n", err) + logger.Logger.Warnf("Server shutdown failed: %v\n", err) } else { fmt.Println("Server stopped gracefully.") + logger.Logger.Info("Server stopped gracefully.") } return } @@ -250,7 +269,8 @@ func startServer() { // Watch for config changes config.Config.OnConfigChange(func(e fsnotify.Event) { - fmt.Println("Config file changed:", e.Name) + logger.Logger.Infof("Config file changed:", e.Name) + logger.Logger.Info("Restarting to apply changes...") fmt.Println("Restarting to apply changes...") restartChan <- struct{}{} }) @@ -258,12 +278,14 @@ func startServer() { // Block until quit signal is received <-quitChan + logger.Logger.Info("Main process exiting.") fmt.Println("Main process exiting.") } func restartServer() { stopServer() fmt.Println("Restarting the Server...") + logger.Logger.Info("Restarting the Server...") time.Sleep(5 * time.Second) startServer() } @@ -272,30 +294,32 @@ func stopServer() { // Read the PID from the file using os.ReadFile data, err := os.ReadFile("packagelock.pid") if err != nil { - fmt.Printf("Could not read PID file: %v\n", err) - return + logger.Logger.Panicf("Could not read PID file: %v\n", err) } pid, err := strconv.Atoi(string(data)) if err != nil { - fmt.Printf("Invalid PID found in file: %v\n", err) - return + logger.Logger.Panicf("Invalid PID found in file: %v\n", err) } // Send SIGTERM to the process fmt.Printf("Stopping the server with PID: %d\n", pid) + logger.Logger.Infof("Stopping the server with PID: %d\n", pid) err = syscall.Kill(pid, syscall.SIGTERM) if err != nil { - fmt.Printf("Failed to stop the server: %v\n", err) + logger.Logger.Warn("Failed to stop the server: %v\n", err) + return + } + + fmt.Println("Server stopped.") + logger.Logger.Info("Server stopped.") + // After successful stop, remove the PID file + err = os.Remove("packagelock.pid") + if err != nil { + logger.Logger.Warnf("Failed to remove PID file: %v\n", err) } else { - fmt.Println("Server stopped.") - // After successful stop, remove the PID file - err = os.Remove("packagelock.pid") - if err != nil { - fmt.Printf("Failed to remove PID file: %v\n", err) - } else { - fmt.Println("PID file removed successfully.") - } + fmt.Println("PID file removed successfully.") + logger.Logger.Info("PID file removed successfully.") } } From 83bb277ea22159755537355035eed8feca3daeab Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:14:45 +0200 Subject: [PATCH 3/9] feat: logging --- server/router.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/router.go b/server/router.go index c93959c..a1c7dae 100644 --- a/server/router.go +++ b/server/router.go @@ -5,6 +5,7 @@ import ( "os" "packagelock/config" "packagelock/handler" + "packagelock/logger" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/recover" @@ -26,6 +27,7 @@ func (r Routes) addAgentHandler(group fiber.Router) { AgentGroup.Get("/:id", handler.GetAgentByID) AgentGroup.Get("/:id/host", handler.GetHostByAgentID) AgentGroup.Post("/register", handler.RegisterAgent) + logger.Logger.Debug("Added Agent Handlers.") } // addGeneralHandler sets up general-related routes in Fiber. @@ -34,6 +36,7 @@ func (r Routes) addGeneralHandler(group fiber.Router) { GeneralGroup.Get("/hosts", handler.GetHosts) GeneralGroup.Get("/agents", handler.GetAgents) + logger.Logger.Debug("Added General Handlers.") } // addHostHandler sets up host-related routes in Fiber. @@ -41,12 +44,16 @@ func (r Routes) addHostHandler(group fiber.Router) { HostGroup := group.Group("/host") HostGroup.Post("/register", handler.RegisterHost) + + logger.Logger.Debug("Added Host Handlers.") } func (r Routes) addLoginHandler(group fiber.Router) { LoginGroup := group.Group("/auth") LoginGroup.Post("/login", handler.LoginHandler) + + logger.Logger.Debug("Added Login Handlers.") } // AddRoutes adds all handler groups to the current Fiber app. @@ -66,6 +73,7 @@ func AddRoutes(Config config.ConfigProvider) Routes { // Use JWT if in production if Config.Get("general.production") == true { + logger.Logger.Info("Enabled Production! Adding JWT!") // Read the private key for JWT keyData, err := os.ReadFile(Config.GetString("network.ssl.privatekeypath")) if err != nil { @@ -73,7 +81,7 @@ func AddRoutes(Config config.ConfigProvider) Routes { } privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyData) if err != nil { - log.Fatal(err) + logger.Logger.Panicf("Can't open Private Key File! Got: %s", err) } // JWT Middleware to protect specific routes @@ -89,6 +97,7 @@ func AddRoutes(Config config.ConfigProvider) Routes { router.addAgentHandler(v1) router.addHostHandler(v1) } else { + logger.Logger.Info("Non-Production Setup! Disabled JWT!") // Create the versioned route group without JWT protection (for non-production environments) v1 := router.Router.Group("/v1") From cd13f0a35e7b606cc1a6e36b2408e8062a51139f Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:15:03 +0200 Subject: [PATCH 4/9] feat: logger & global var logger.Logger --- logger/logger.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 logger/logger.go diff --git a/logger/logger.go b/logger/logger.go new file mode 100644 index 0000000..a2db5fb --- /dev/null +++ b/logger/logger.go @@ -0,0 +1,42 @@ +package logger + +import ( + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var Logger *zap.SugaredLogger + +// InitLogger initializes the zap.Logger once and returns the instance. +func InitLogger() (*zap.SugaredLogger, error) { + var err error + + // Ensure the logger is initialized only once + loggerConfig := zap.Config{ + Encoding: "console", // You can also use "json" + OutputPaths: []string{"logs/app.log"}, + ErrorOutputPaths: []string{"logs/app_error.log"}, + Level: zap.NewAtomicLevelAt(zapcore.InfoLevel), + EncoderConfig: zapcore.EncoderConfig{ + TimeKey: "timestamp", + LevelKey: "level", + NameKey: "logger", + CallerKey: "caller", + MessageKey: "msg", + StacktraceKey: "stacktrace", + LineEnding: zapcore.DefaultLineEnding, + EncodeLevel: zapcore.CapitalLevelEncoder, + EncodeTime: zapcore.ISO8601TimeEncoder, + EncodeDuration: zapcore.StringDurationEncoder, + EncodeCaller: zapcore.ShortCallerEncoder, + }, + } + // Build the logger + logger, err := loggerConfig.Build() + if err != nil { + // Handle logger initialization error (no panic) + logger = nil + } + // Return the initialized logger and any error that occurred + return logger.Sugar(), err +} From 9b16074d3439dba28af59f38f30ad599ab20381a Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:15:16 +0200 Subject: [PATCH 5/9] feat: logging & error handling --- handler/UserGroup.go | 34 +++++++++++++------- handler/agentgroup.go | 70 ++++++++++++++++++++++++----------------- handler/generalgroup.go | 29 ++++++++++++----- handler/hostgroup.go | 8 +++-- 4 files changed, 90 insertions(+), 51 deletions(-) diff --git a/handler/UserGroup.go b/handler/UserGroup.go index bf264b6..47ce4bd 100644 --- a/handler/UserGroup.go +++ b/handler/UserGroup.go @@ -1,10 +1,10 @@ package handler import ( - "log" "os" "packagelock/config" "packagelock/db" + "packagelock/logger" "packagelock/structs" "time" @@ -23,6 +23,7 @@ func LoginHandler(c *fiber.Ctx) error { // Cast POST var loginReq LoginRequest if err := c.BodyParser(&loginReq); err != nil { + logger.Logger.Debugf("Got invalid Login Request: %s", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Failed to parse request", }) @@ -30,15 +31,15 @@ func LoginHandler(c *fiber.Ctx) error { data, err := db.DB.Select("user") if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Got error while 'db.DB.Select('user')': %s \nSending 'StatusInternalServerError'", err) + return c.Status(fiber.StatusInternalServerError).JSON(nil) } var UserTable []structs.User err = surrealdb.Unmarshal(data, &UserTable) if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Got error while surrealdb.Unmarshal: %s \nSending 'StatusInternalServerError'", err) + return c.Status(fiber.StatusInternalServerError).JSON(nil) } var authenticatedUser structs.User @@ -46,7 +47,6 @@ func LoginHandler(c *fiber.Ctx) error { // TODO: implement password hashing if possibleUser.Username == loginReq.Username && possibleUser.Password == loginReq.Password { authenticatedUser = possibleUser - // TODO: log token creation } } @@ -60,15 +60,23 @@ func LoginHandler(c *fiber.Ctx) error { // Sign and get the encoded token keyData, err := os.ReadFile(config.Config.GetString("network.ssl-config.privatekeypath")) if err != nil { - log.Fatal(err) + logger.Logger.Warnf("Can't read from Private Key File, got: %s\nPath: %s", err, config.Config.GetString("network.ssl-config.privatekeypath")) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate token", + }) } + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(keyData) if err != nil { - log.Fatal(err) + logger.Logger.Warnf("Can't sign with Private Key File, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate token", + }) } + tokenString, err := token.SignedString(privateKey) if err != nil { - // FIXME: error handling & maybe logging to? + logger.Logger.Warnf("Can't generate JWT, got: %s", err) return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "Failed to generate token", }) @@ -87,14 +95,16 @@ func LoginHandler(c *fiber.Ctx) error { // Add the token to the user's APIToken slice authenticatedUser.ApiKeys = append(authenticatedUser.ApiKeys, newJWT) - authenticatedUser.UpdateTime = time.Now() _, err = db.DB.Update(authenticatedUser.ID, authenticatedUser) if err != nil { - // FIXME: errorhandling - panic(err) + logger.Logger.Warnf("Can't update User entry in DB to append new JWT, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to generate token", + }) } + logger.Logger.Infof("Successfully authenticated and authorized following User: %s", authenticatedUser.Username) return c.JSON(newJWT) } diff --git a/handler/agentgroup.go b/handler/agentgroup.go index b974034..1016aa1 100644 --- a/handler/agentgroup.go +++ b/handler/agentgroup.go @@ -3,6 +3,7 @@ package handler import ( "encoding/base64" "packagelock/db" + "packagelock/logger" "packagelock/structs" "github.com/gofiber/fiber/v2" @@ -15,35 +16,41 @@ func GetAgentByID(c *fiber.Ctx) error { // ID is an URL slice. Its a URL-Save base64 encoded UUID urlIDBytes, err := base64.RawURLEncoding.DecodeString(c.Params("id")) if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Can't parse AgentID from URL, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to parse AgentID.", + }) } urlIDString := string(urlIDBytes) agents, err := db.DB.Select("agents") if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to fetch 'agents' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch Agents.", + }) } var agentsSlice []structs.Agent err = surrealdb.Unmarshal(agents, &agentsSlice) if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to unmarshal agents, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed Unmarshal.", + }) } var requestedAgentByID structs.Agent for _, agent := range agentsSlice { if agent.AgentID.String() == urlIDString { requestedAgentByID = agent - // FIXME: logging return c.Status(fiber.StatusOK).JSON(requestedAgentByID) } } + + logger.Logger.Warnf("Got Request for agent with id: %s, which dosn't exist!", urlIDString) return c.Status(fiber.StatusNotFound).JSON(nil) - // FIXME: logging } // RegisterAgent handles POST requests to register a new agent. @@ -52,8 +59,7 @@ func RegisterAgent(c *fiber.Ctx) error { // Parse the JSON request body into newAgent if err := c.BodyParser(&newAgent); err != nil { - // TODO: Add logs - // TODO: Add error handling + logger.Logger.Warnf("Cannot parse JSON into new Agent! Got: %s", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Cannot parse JSON", }) @@ -61,11 +67,11 @@ func RegisterAgent(c *fiber.Ctx) error { newAgentInsertionData, err := db.DB.Create("agents", newAgent) if err != nil { - // FIXME: logging - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Can't insert new Agent into DB, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(nil) } // Respond with the newly created agent + logger.Logger.Infof("Successfully Created new Agent with ID: %s", newAgent.AgentID) return c.Status(fiber.StatusCreated).JSON(newAgentInsertionData) } @@ -73,23 +79,29 @@ func RegisterAgent(c *fiber.Ctx) error { func GetHostByAgentID(c *fiber.Ctx) error { urlIDBytes, err := base64.RawURLEncoding.DecodeString(c.Params("id")) if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Can't parse AgentID from URL, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to parse AgentID.", + }) } urlIDString := string(urlIDBytes) agents, err := db.DB.Select("agents") if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to fetch 'agents' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch Agents.", + }) } var agentsSlice []structs.Agent err = surrealdb.Unmarshal(agents, &agentsSlice) if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to unmarshal agents, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed Unmarshal.", + }) } var requestedAgentByID structs.Agent @@ -99,7 +111,9 @@ func GetHostByAgentID(c *fiber.Ctx) error { } } + // if no matching agent is found, the ID is empty if requestedAgentByID.ID == "" { + logger.Logger.Warnf("Got Request for agent with id: %s, which dosn't exist!", urlIDString) return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "error": "Agent not found", }) @@ -107,30 +121,30 @@ func GetHostByAgentID(c *fiber.Ctx) error { hosts, err := db.DB.Select("hosts") if err != nil { - // FIXME: Logging! - // FIXME: Error handling! - panic(err) + logger.Logger.Warnf("Failed to fetch 'hosts' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch Hosts.", + }) } var hostsSlice []structs.Host err = surrealdb.Unmarshal(hosts, &hostsSlice) if err != nil { - // FIXME: errorhandling - // FIXME: errorhandling - panic(err) + logger.Logger.Warnf("Failed to unmarshal hosts, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed Unmarshal.", + }) } var requestedHostByAgentID structs.Host for _, host := range hostsSlice { if host.HostID == requestedAgentByID.HostID { requestedHostByAgentID = host - // FIXME: Logging return c.Status(fiber.StatusOK).JSON(requestedHostByAgentID) } } - // IF HERE: - // No Host or No agent found + logger.Logger.Warnf("Agent Found, but no Host is associated... Thats Weird. AgentID: %s", requestedAgentByID.AgentID) return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ "error": "Agent Found, but no Host is associated... Thats Weird.", }) diff --git a/handler/generalgroup.go b/handler/generalgroup.go index 6b398d6..68727d7 100644 --- a/handler/generalgroup.go +++ b/handler/generalgroup.go @@ -2,6 +2,7 @@ package handler import ( "packagelock/db" + "packagelock/logger" "packagelock/structs" "github.com/gofiber/fiber/v2" @@ -12,15 +13,21 @@ import ( func GetHosts(c *fiber.Ctx) error { hosts, err := db.DB.Select("hosts") if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to fetch 'hosts' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch hosts.", + }) } + var hostsSlice []structs.Host err = surrealdb.Unmarshal(hosts, &hostsSlice) if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to unmarshal hosts, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed Unmarshal.", + }) } + return c.Status(fiber.StatusOK).JSON(hostsSlice) } @@ -28,14 +35,20 @@ func GetHosts(c *fiber.Ctx) error { func GetAgents(c *fiber.Ctx) error { agents, err := db.DB.Select("agents") if err != nil { - // FIXME: Error handling - panic(err) + logger.Logger.Warnf("Failed to fetch 'agents' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch agents.", + }) } + var agentsSlice []structs.Host err = surrealdb.Unmarshal(agents, &agentsSlice) if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Failed to fetch 'agents' from db, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to fetch agents.", + }) } + return c.Status(fiber.StatusOK).JSON(agentsSlice) } diff --git a/handler/hostgroup.go b/handler/hostgroup.go index 4200b48..ba00f76 100644 --- a/handler/hostgroup.go +++ b/handler/hostgroup.go @@ -2,6 +2,7 @@ package handler import ( "packagelock/db" + "packagelock/logger" "packagelock/structs" "github.com/gofiber/fiber/v2" @@ -13,6 +14,7 @@ func RegisterHost(c *fiber.Ctx) error { // Parse the JSON request body into newHost if err := c.BodyParser(&newHost); err != nil { + logger.Logger.Warnf("Cannot parse JSON into new Host! Got: %s", err) return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "Cannot parse JSON", }) @@ -20,10 +22,10 @@ func RegisterHost(c *fiber.Ctx) error { transaction, err := db.DB.Create("hosts", newHost) if err != nil { - // FIXME: error handling - panic(err) + logger.Logger.Warnf("Can't insert new Host into DB, got: %s", err) + return c.Status(fiber.StatusInternalServerError).JSON(nil) } - // FIXME: Logging! + logger.Logger.Infof("Successfully Created new Host with ID: %s", newHost.HostID) return c.Status(fiber.StatusCreated).JSON(transaction) } From d93eb34f2669d33894cecbb36cb232e998e4b761 Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:15:28 +0200 Subject: [PATCH 6/9] feat: logging --- db/db.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/db/db.go b/db/db.go index 0b4b0bd..20e3d86 100644 --- a/db/db.go +++ b/db/db.go @@ -1,8 +1,8 @@ package db import ( - "fmt" "packagelock/config" + "packagelock/logger" "github.com/surrealdb/surrealdb.go" ) @@ -17,41 +17,38 @@ func InitDB() error { db, err := surrealdb.New("ws://" + dbAddress + ":" + dbPort + "/rpc") if err != nil { - errorMessage := fmt.Sprintf(` Couldn't connect to DB! Got: '%s'. + logger.Logger.Errorf(` Couldn't connect to DB! Got: '%s'. 1. Check the config for a wrong Address/Port (Currently: %s:%s) 2. Check if the DB is reachable (eg. a Ping). Check the Firewalls if there. 3. Consult the PackageLock Doc's! 🚀 Golang Trace Logs: `, err.Error(), dbAddress, dbPort) - fmt.Println(errorMessage) - panic(err) } if _, err = db.Signin(map[string]interface{}{ - // TODO: get user&password from Conf "user": dbUsername, "pass": dbPasswd, }); err != nil { - errorMessage := fmt.Sprintf(` Couldn't connect to DB! Got: '%s'. + logger.Logger.Errorf(` Couldn't connect to DB! Got: '%s'. 1. Check the config for a wrong DB-Username/Password (Currently: %s/) 3. Consult the PackageLock Doc's! 🚀 Golang Trace Logs: `, err.Error(), dbUsername) - fmt.Println(errorMessage) - panic(err) } if _, err = db.Use("PackageLock", "db1.0"); err != nil { // No error handling possible, as we need to use this db - panic(err) + logger.Logger.Panicf("Couldn't Use 'PackageLock' Namespace and 'db1.0' Database. Got: %s", err) } DB = db + logger.Logger.Infof("Successfully Connected to DB, at: %s:%s", dbAddress, dbPort) return nil } // INFO: If you use this, fix it! +// INFO: And add logging/error handling func Select(tablename string, SliceOfType interface{}) error { transaction, err := DB.Select(tablename) if err != nil { From 9070460b239bba21dd6312940316ff8a73b3221f Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:15:48 +0200 Subject: [PATCH 7/9] feat: logging --- config/conf-init.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/config/conf-init.go b/config/conf-init.go index e969df5..36cd6a1 100644 --- a/config/conf-init.go +++ b/config/conf-init.go @@ -2,8 +2,8 @@ package config import ( "bytes" - "fmt" "io" + "packagelock/logger" "github.com/fsnotify/fsnotify" "github.com/spf13/viper" @@ -43,17 +43,18 @@ func StartViper(config ConfigProvider) ConfigProvider { if _, ok := err.(viper.ConfigFileNotFoundError); ok { CreateDefaultConfig(config) new_config := StartViper(config) + logger.Logger.Info("No Config found, created default Config.") return new_config } else { - panic(fmt.Errorf("fatal error config file: %w", err)) + logger.Logger.Panicf("Cannot create default config, got: %s", err) } } + logger.Logger.Info("Successfully Created Config Manager.") return config } func CreateDefaultConfig(config ConfigProvider) { - // TODO: Add default config yamlExample := []byte(` general: debug: true @@ -75,11 +76,11 @@ network: err := config.ReadConfig(bytes.NewBuffer(yamlExample)) if err != nil { - panic(fmt.Errorf("fatal error while reading config file: %w", err)) + logger.Logger.Panicf("Incompatible Default Config! Got: %s", err) } err_write := config.WriteConfigAs("./config.yaml") if err_write != nil { - panic(fmt.Errorf("fatal error while writing config file: %w", err)) + logger.Logger.Panicf("Cannot write config file, got: %s", err) } } From 288ec5e4dae1a93c20b4cb36197077680f9d52e5 Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:15:59 +0200 Subject: [PATCH 8/9] chore: rem old files --- config/conf-init_test.go.ignore | 16 ---- config/mockgen.go.ignore | 143 -------------------------------- 2 files changed, 159 deletions(-) delete mode 100644 config/conf-init_test.go.ignore delete mode 100644 config/mockgen.go.ignore diff --git a/config/conf-init_test.go.ignore b/config/conf-init_test.go.ignore deleted file mode 100644 index 33abc11..0000000 --- a/config/conf-init_test.go.ignore +++ /dev/null @@ -1,16 +0,0 @@ -package config - - -import () - - -type MockConfigProvider interface { - SetConfigName func() - SetConfigType func() - AddConfigPath func() - ReadInConfig func() - OnConfigChange func() - WatchConfig func() -} - - diff --git a/config/mockgen.go.ignore b/config/mockgen.go.ignore deleted file mode 100644 index 6c83fb5..0000000 --- a/config/mockgen.go.ignore +++ /dev/null @@ -1,143 +0,0 @@ -// Code generated by MockGen. DO NOT EDIT. -// Source: config/conf-init.go -// -// Generated by this command: -// -// mockgen -source=config/conf-init.go -// - -// Package mock_config is a generated GoMock package. -package mock_config - -import ( - io "io" - reflect "reflect" - - fsnotify "github.com/fsnotify/fsnotify" - gomock "go.uber.org/mock/gomock" -) - -// MockConfigProvider is a mock of ConfigProvider interface. -type MockConfigProvider struct { - ctrl *gomock.Controller - recorder *MockConfigProviderMockRecorder -} - -// MockConfigProviderMockRecorder is the mock recorder for MockConfigProvider. -type MockConfigProviderMockRecorder struct { - mock *MockConfigProvider -} - -// NewMockConfigProvider creates a new mock instance. -func NewMockConfigProvider(ctrl *gomock.Controller) *MockConfigProvider { - mock := &MockConfigProvider{ctrl: ctrl} - mock.recorder = &MockConfigProviderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockConfigProvider) EXPECT() *MockConfigProviderMockRecorder { - return m.recorder -} - -// AddConfigPath mocks base method. -func (m *MockConfigProvider) AddConfigPath(path string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "AddConfigPath", path) -} - -// AddConfigPath indicates an expected call of AddConfigPath. -func (mr *MockConfigProviderMockRecorder) AddConfigPath(path any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddConfigPath", reflect.TypeOf((*MockConfigProvider)(nil).AddConfigPath), path) -} - -// OnConfigChange mocks base method. -func (m *MockConfigProvider) OnConfigChange(run func(fsnotify.Event)) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "OnConfigChange", run) -} - -// OnConfigChange indicates an expected call of OnConfigChange. -func (mr *MockConfigProviderMockRecorder) OnConfigChange(run any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OnConfigChange", reflect.TypeOf((*MockConfigProvider)(nil).OnConfigChange), run) -} - -// ReadConfig mocks base method. -func (m *MockConfigProvider) ReadConfig(in io.Reader) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadConfig", in) - ret0, _ := ret[0].(error) - return ret0 -} - -// ReadConfig indicates an expected call of ReadConfig. -func (mr *MockConfigProviderMockRecorder) ReadConfig(in any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadConfig", reflect.TypeOf((*MockConfigProvider)(nil).ReadConfig), in) -} - -// ReadInConfig mocks base method. -func (m *MockConfigProvider) ReadInConfig() error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ReadInConfig") - ret0, _ := ret[0].(error) - return ret0 -} - -// ReadInConfig indicates an expected call of ReadInConfig. -func (mr *MockConfigProviderMockRecorder) ReadInConfig() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadInConfig", reflect.TypeOf((*MockConfigProvider)(nil).ReadInConfig)) -} - -// SetConfigName mocks base method. -func (m *MockConfigProvider) SetConfigName(name string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetConfigName", name) -} - -// SetConfigName indicates an expected call of SetConfigName. -func (mr *MockConfigProviderMockRecorder) SetConfigName(name any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetConfigName", reflect.TypeOf((*MockConfigProvider)(nil).SetConfigName), name) -} - -// SetConfigType mocks base method. -func (m *MockConfigProvider) SetConfigType(fileext string) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "SetConfigType", fileext) -} - -// SetConfigType indicates an expected call of SetConfigType. -func (mr *MockConfigProviderMockRecorder) SetConfigType(fileext any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetConfigType", reflect.TypeOf((*MockConfigProvider)(nil).SetConfigType), fileext) -} - -// WatchConfig mocks base method. -func (m *MockConfigProvider) WatchConfig() { - m.ctrl.T.Helper() - m.ctrl.Call(m, "WatchConfig") -} - -// WatchConfig indicates an expected call of WatchConfig. -func (mr *MockConfigProviderMockRecorder) WatchConfig() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WatchConfig", reflect.TypeOf((*MockConfigProvider)(nil).WatchConfig)) -} - -// WriteConfigAs mocks base method. -func (m *MockConfigProvider) WriteConfigAs(path string) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "WriteConfigAs", path) - ret0, _ := ret[0].(error) - return ret0 -} - -// WriteConfigAs indicates an expected call of WriteConfigAs. -func (mr *MockConfigProviderMockRecorder) WriteConfigAs(path any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteConfigAs", reflect.TypeOf((*MockConfigProvider)(nil).WriteConfigAs), path) -} From c1b15af0027b3a1c3323b8d233cbcfd9cba7a215 Mon Sep 17 00:00:00 2001 From: HilkopterBob Date: Tue, 8 Oct 2024 08:16:05 +0200 Subject: [PATCH 9/9] feat: logging --- certs/generate-certs.go | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/certs/generate-certs.go b/certs/generate-certs.go index c7eaaf9..bbd6db9 100644 --- a/certs/generate-certs.go +++ b/certs/generate-certs.go @@ -6,9 +6,9 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" - "fmt" "math/big" "os" + "packagelock/logger" "time" ) @@ -17,7 +17,8 @@ func CreateSelfSignedCert(certFile, keyFile string) error { // Generate a private key using RSA (2048-bit key size) priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { - return fmt.Errorf("failed to generate private key: %v", err) + logger.Logger.Warnf("failed to generate private key: %v", err) + return err } // Create a certificate template @@ -26,7 +27,8 @@ func CreateSelfSignedCert(certFile, keyFile string) error { serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) if err != nil { - return fmt.Errorf("failed to generate serial number: %v", err) + logger.Logger.Warnf("failed to generate serial number: %v", err) + return err } template := x509.Certificate{ @@ -44,49 +46,55 @@ func CreateSelfSignedCert(certFile, keyFile string) error { // Generate a self-signed certificate using the RSA private key certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { - return fmt.Errorf("failed to create certificate: %v", err) + logger.Logger.Warnf("failed to create certificate: %v", err) + return err } // Save the certificate to certFile certOut, err := os.Create(certFile) if err != nil { - return fmt.Errorf("failed to open cert.pem for writing: %v", err) + logger.Logger.Warnf("failed to open cert.pem for writing: %v", err) } // INFO: If the parrent throws an err and this defer is called // and fileOut.Close() throws an error to, the original error will be overwritten. defer func() { - err := certOut.Close() - if err != nil { - panic(err) + deferredErr := certOut.Close() + if deferredErr != nil { + logger.Logger.Warnf("Cannot close Cert File, got: %s", deferredErr) + return } }() if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil { - return fmt.Errorf("failed to write certificate to cert.pem: %v", err) + logger.Logger.Warnf("failed to write certificate to cert.pem: %v", err) + return err } // Save the RSA private key to keyFile keyOut, err := os.Create(keyFile) if err != nil { - return fmt.Errorf("failed to open key.pem for writing: %v", err) + logger.Logger.Warnf("failed to open key.pem for writing: %v", err) + return err } // INFO: If the parrent throws an err and this defer is called // and fileOut.Close() throws an error to, the original error will be overwritten. defer func() { - err := keyOut.Close() - if err != nil { - panic(err) + deferredErr := keyOut.Close() + if deferredErr != nil { + logger.Logger.Warnf("Cannot close Cert File, got: %s", deferredErr) + return } }() // Marshal the RSA private key privBytes := x509.MarshalPKCS1PrivateKey(priv) if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes}); err != nil { - return fmt.Errorf("failed to write private key to key.pem: %v", err) + logger.Logger.Warnf("failed to write private key to key.pem: %v", err) + return err } - fmt.Println("Successfully created self-signed RSA certificate and private key.") + logger.Logger.Infof("Successfully created self-signed RSA certificate and private key.\n%s \n%s", certFile, keyFile) return nil }