Skip to content
This repository has been archived by the owner on May 30, 2022. It is now read-only.

Store runner check results in the database #652

Merged
merged 8 commits into from
Dec 23, 2021
14 changes: 14 additions & 0 deletions web/entities/check_result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package entities

import (
"time"

"gorm.io/datatypes"
)

type ChecksResult struct {
ID int64
CreatedAt time.Time
GroupID string
Payload datatypes.JSON
}
45 changes: 0 additions & 45 deletions web/models/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,6 @@ import (
"sort"
)

const (
CheckPassing string = "passing"
CheckWarning string = "warning"
CheckCritical string = "critical"
CheckSkipped string = "skipped"
CheckUndefined string = "undefined"
)

type CheckData struct {
Metadata Metadata `json:"metadata,omitempty" mapstructure:"metadata,omitempty"`
Groups map[string]*Results `json:"results,omitempty" mapstructure:"results,omitempty"`
}

// List is used instead of a map as it guarantees order
type ChecksCatalog []*Check

Expand All @@ -41,38 +28,6 @@ type GroupedChecks struct {

type GroupedCheckList []*GroupedChecks

type Metadata struct {
Checks ChecksCatalog `json:"checks,omitempty" mapstructure:"checks,omitempty"`
}

type Results struct {
Hosts map[string]*CheckHost `json:"hosts,omitempty" mapstructure:"hosts,omitempty"`
Checks map[string]*ChecksByHost `json:"checks,omitempty" mapstructure:"checks,omitempty"`
}

// The ChecksByHost struct stores the checks list, but the results are grouped by hosts
type ChecksByHost struct {
Hosts map[string]*Check `json:"hosts,omitempty" mapstructure:"hosts,omitempty"`
}

type CheckHost struct {
Reachable bool `json:"reachable" mapstructure:"reachable"`
Msg string `json:"msg" mapstructure:"msg"`
}

// Simplified models for the frontend
type ClusterCheckResults struct {
Hosts map[string]*CheckHost `json:"hosts" mapstructure:"hosts,omitempty"`
Checks []ClusterCheckResult `json:"checks" mapstructure:"checks,omitempty"`
}

type ClusterCheckResult struct {
ID string `json:"id,omitempty" mapstructure:"id,omitempty"`
Hosts map[string]*Check `json:"hosts,omitempty" mapstructure:"hosts,omitempty"`
Group string `json:"group,omitempty" mapstructure:"group,omitempty"`
Description string `json:"description,omitempty" mapstructure:"description,omitempty"`
}

// Sorting methods for GroupedCheckList

func (g GroupedCheckList) Len() int {
Expand Down
33 changes: 33 additions & 0 deletions web/models/check_result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package models

const (
CheckPassing string = "passing"
CheckWarning string = "warning"
CheckCritical string = "critical"
CheckSkipped string = "skipped"
CheckUndefined string = "undefined"
)

type ChecksResult struct {
Hosts map[string]*HostState `json:"hosts,omitempty"`
Checks map[string]*ChecksByHost `json:"checks,omitempty"`
}

// Simplifed stuct consumed by the frontend
type ChecksResultAsList struct {
Hosts map[string]*HostState `json:"hosts,omitempty"`
Checks []*ChecksByHost `json:"checks,omitempty"`
}

// The ChecksByHost struct stores the checks list, but the results are grouped by hosts
type ChecksByHost struct {
Hosts map[string]*Check `json:"hosts,omitempty"`
ID string `json:"id,omitempty"`
Group string `json:"group,omitempty"`
Description string `json:"description,omitempty"`
}

type HostState struct {
Reachable bool `json:"reachable"`
Msg string `json:"msg"`
}
60 changes: 22 additions & 38 deletions web/services/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ package services
import (
"encoding/json"
"errors"
"fmt"

"github.com/mitchellh/mapstructure"
"gorm.io/datatypes"
"gorm.io/gorm"
"gorm.io/gorm/clause"

"github.com/trento-project/trento/web/entities"
"github.com/trento-project/trento/web/models"
"github.com/trento-project/trento/web/services/ara"
)

//go:generate mockery --name=ChecksService --inpackage --filename=checks_mock.go
Expand Down Expand Up @@ -41,9 +38,9 @@ type ChecksService interface {
CreateChecksCatalogEntry(check *models.Check) error // seems to be never used
CreateChecksCatalog(checkList models.ChecksCatalog) error
// Check result services
GetChecksResult() (map[string]*models.Results, error)
GetChecksResultByCluster(clusterId string) (*models.Results, error)
GetChecksResultAndMetadataByCluster(clusterId string) (*models.ClusterCheckResults, error)
CreateChecksResultById(id string, checksResult *models.ChecksResult) error
GetChecksResultByCluster(clusterId string) (*models.ChecksResult, error)
GetChecksResultAndMetadataByCluster(clusterId string) (*models.ChecksResultAsList, error)
GetAggregatedChecksResultByHost(clusterId string) (map[string]*AggregatedCheckData, error)
GetAggregatedChecksResultByCluster(clusterId string) (*AggregatedCheckData, error)
// Selected checks services
Expand All @@ -57,14 +54,12 @@ type ChecksService interface {

type checksService struct {
db *gorm.DB
araService ara.AraService
premiumDetectionService PremiumDetectionService
}

func NewChecksService(db *gorm.DB, araService ara.AraService, premiumDetectionService PremiumDetectionService) *checksService {
func NewChecksService(db *gorm.DB, premiumDetectionService PremiumDetectionService) *checksService {
return &checksService{
db: db,
araService: araService,
premiumDetectionService: premiumDetectionService,
}
}
Expand Down Expand Up @@ -159,43 +154,32 @@ func (c *checksService) CreateChecksCatalog(checkList models.ChecksCatalog) erro
Checks result services
*/

func (c *checksService) GetChecksResult() (map[string]*models.Results, error) {
var checkData = models.CheckData{}

records, err := c.araService.GetRecordList("key=trento-results&order=-id")
if err != nil {
return nil, err
}

if len(records.Results) == 0 {
return nil, fmt.Errorf("Couldn't find any check result record. Check if the runner component is running")
}

record, err := c.araService.GetRecord(records.Results[0].ID)
func (c *checksService) CreateChecksResultById(id string, checksResult *models.ChecksResult) error {
jsonData, err := json.Marshal(&checksResult)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't use the ById for a create method, wouldn't be possibile to add the id field to the model directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we can do so.
I will do the change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fabriziosestito To understand it better. Do you only refer to change the CreateChecksResultById method or the whole endpoint checks/:id/results ?

Copy link
Contributor Author

@arbulu89 arbulu89 Dec 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in: b0efa61
50ecfc2

if err != nil {
return nil, err
return err
}

mapstructure.Decode(record.Value, &checkData)
event := entities.ChecksResult{GroupID: id, Payload: jsonData}
result := c.db.Create(&event)

return checkData.Groups, nil
return result.Error
}

func (c *checksService) GetChecksResultByCluster(clusterId string) (*models.Results, error) {
cResult, err := c.GetChecksResult()
if err != nil {
return nil, err
}
func (c *checksService) GetChecksResultByCluster(clusterId string) (*models.ChecksResult, error) {
var checksResult entities.ChecksResult
result := c.db.Where("group_id", clusterId).Last(&checksResult)

cResultByCluster, ok := cResult[clusterId]
if !ok {
return nil, fmt.Errorf("Cluster %s not found", clusterId)
if result.Error != nil {
return nil, result.Error
}

return cResultByCluster, nil
var checksResultModel models.ChecksResult
err := json.Unmarshal(checksResult.Payload, &checksResultModel)
return &checksResultModel, err
}

func (c *checksService) GetChecksResultAndMetadataByCluster(clusterId string) (*models.ClusterCheckResults, error) {
func (c *checksService) GetChecksResultAndMetadataByCluster(clusterId string) (*models.ChecksResultAsList, error) {
cResultByCluster, err := c.GetChecksResultByCluster(clusterId)
if err != nil {
return nil, err
Expand All @@ -206,14 +190,14 @@ func (c *checksService) GetChecksResultAndMetadataByCluster(clusterId string) (*
return nil, err
}

resultSet := &models.ClusterCheckResults{}
resultSet := &models.ChecksResultAsList{}
resultSet.Hosts = cResultByCluster.Hosts
resultSet.Checks = []models.ClusterCheckResult{}
resultSet.Checks = []*models.ChecksByHost{}

for _, checkMeta := range checkList {
for checkId, checkByHost := range cResultByCluster.Checks {
if checkId == checkMeta.ID {
current := models.ClusterCheckResult{
current := &models.ChecksByHost{
Group: checkMeta.Group,
Description: checkMeta.Description,
Hosts: checkByHost.Hosts,
Expand Down
53 changes: 22 additions & 31 deletions web/services/checks_mock.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.