diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d8e9a87..dc5157a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,6 +71,7 @@ jobs: mkdir -p $SERVER_BIN_PATH mkdir -p $SERVER_BIN_PATH/reports mkdir -p $SERVER_BIN_PATH/wmi + mkdir -p $SERVER_BIN_PATH/logs mkdir -p $SERVER_BIN_PATH/storage mv wmi.so $SERVER_BIN_PATH/wmi/ mv storage/alternatives.csv $SERVER_BIN_PATH/storage/ diff --git a/app/controllers/discoveries/discoveries.go b/app/controllers/discoveries/discoveries.go index c7ced40..d60c007 100644 --- a/app/controllers/discoveries/discoveries.go +++ b/app/controllers/discoveries/discoveries.go @@ -1,9 +1,13 @@ package discoveries import ( + "os" + "path" + "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/limanmys/inventory-server/app/entities" + "github.com/limanmys/inventory-server/internal/constants" "github.com/limanmys/inventory-server/internal/database" "github.com/limanmys/inventory-server/internal/paginator" "github.com/limanmys/inventory-server/internal/search" @@ -36,8 +40,19 @@ func Create(c *fiber.Ctx) error { return err } + // Set run id + runID := uuid.New().String() + + // Create discovery logs record + if err := database.Connection().Create(&entities.DiscoveryLogs{ + DiscoveryID: payload.ID, + Filename: runID, + }).Error; err != nil { + return err + } + // Start discovery - go discovery.Start(payload) + go discovery.Start(payload, runID) return c.JSON(payload) } @@ -45,19 +60,30 @@ func Create(c *fiber.Ctx) error { // Run, runs a discovery func Run(c *fiber.Ctx) error { // Check uuid validity - uuid, err := uuid.Parse(c.Params("id")) + uid, err := uuid.Parse(c.Params("id")) if err != nil { return err } // Get discovery var discoveryObject entities.Discovery - if err := database.Connection().Model(&entities.Discovery{}).Where("id = ?", uuid).First(&discoveryObject).Error; err != nil { + if err := database.Connection().Model(&entities.Discovery{}).Where("id = ?", uid).First(&discoveryObject).Error; err != nil { + return err + } + + // Set run id + runID := uuid.New().String() + + // Create discovery logs record + if err := database.Connection().Create(&entities.DiscoveryLogs{ + DiscoveryID: discoveryObject.ID, + Filename: runID, + }).Error; err != nil { return err } // Start discovery - go discovery.Start(discoveryObject) + go discovery.Start(discoveryObject, runID) return c.JSON("Discovery started successfully.") } @@ -101,3 +127,27 @@ func Delete(c *fiber.Ctx) error { return c.JSON("Record deleted successfully.") } + +// ReadLog, Reads a latest log file +func ReadLatestLog(c *fiber.Ctx) error { + // Check uuid validity + uuid, err := uuid.Parse(c.Params("id")) + if err != nil { + return err + } + + // Get logs + var log entities.DiscoveryLogs + if err := database.Connection().Model(&entities.DiscoveryLogs{}). + Where("discovery_id = ?", uuid).Order("updated_at DESC").First(&log).Error; err != nil { + return err + } + + // Read content + content, err := os.ReadFile(path.Join(constants.DEFAULT_LOG_PATH, log.Filename)) + if err != nil { + return err + } + + return c.JSON(fiber.Map{"content": string(content)}) +} diff --git a/app/entities/Discovery.go b/app/entities/Discovery.go index 89731d1..fa4354f 100644 --- a/app/entities/Discovery.go +++ b/app/entities/Discovery.go @@ -29,3 +29,10 @@ func (d *Discovery) UpdateStatus(status Status, message string) { d.Message = message database.Connection().Model(d).Save(d) } + +type DiscoveryLogs struct { + Base + DiscoveryID *uuid.UUID `json:"discovery_id"` + Discovery *Discovery `json:"discovery"` + Filename string `json:"filename"` +} diff --git a/app/entities/Result.go b/app/entities/Result.go index 8fc858e..b041f98 100644 --- a/app/entities/Result.go +++ b/app/entities/Result.go @@ -9,4 +9,5 @@ type Arguments struct { IPRange string `json:"ip_range"` Username string `json:"string"` Password string `json:"password"` + RunID string `json:"run_id"` } diff --git a/app/routes/routes.go b/app/routes/routes.go index 68b6dca..c3d4416 100644 --- a/app/routes/routes.go +++ b/app/routes/routes.go @@ -27,6 +27,8 @@ func Routes(app *fiber.App) { // Discovery routes discoveryGroup := app.Group("/discoveries") { + // Read latest log + discoveryGroup.Get("/logs/:id", discoveries.ReadLatestLog) // Create record discoveryGroup.Post("/", discoveries.Create) // Run discovery diff --git a/internal/constants/constants.go b/internal/constants/constants.go index 7478384..24a5060 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -4,4 +4,5 @@ const ( REPORT_SAVE_PATH = "./reports/" WMI_SO_PATH = "./wmi/wmi.so" ALTERNATIVES_CSV_PATH = "./storage/alternatives.csv" + DEFAULT_LOG_PATH = "/opt/inventory-server/logs" ) diff --git a/internal/migrations/migrate.go b/internal/migrations/migrate.go index f54b96b..276abe9 100644 --- a/internal/migrations/migrate.go +++ b/internal/migrations/migrate.go @@ -24,5 +24,8 @@ func Migrate() error { if err := database.Connection().AutoMigrate(&entities.Job{}); err != nil { return err } + if err := database.Connection().AutoMigrate(&entities.DiscoveryLogs{}); err != nil { + return err + } return nil } diff --git a/pkg/discovery/discovery.go b/pkg/discovery/discovery.go index 574214a..949ce7f 100644 --- a/pkg/discovery/discovery.go +++ b/pkg/discovery/discovery.go @@ -14,7 +14,7 @@ import ( "gorm.io/gorm/clause" ) -func Start(discovery entities.Discovery) { +func Start(discovery entities.Discovery, run_id string) { // Open c-shared library lib, err := dl.Open(constants.WMI_SO_PATH, 0) if err != nil { @@ -57,6 +57,7 @@ func Start(discovery entities.Discovery) { IPRange: discovery.IPRange, Username: profile.Username, Password: profile.Password, + RunID: run_id, }) if err != nil { discovery.UpdateStatus(entities.StatusError, "error when marshalling arguments, err: "+err.Error())