Skip to content

Commit

Permalink
feat: health expression on components (#944)
Browse files Browse the repository at this point in the history
* feat: health expression on components

* fix: lint errors

* chore: drop status_expr

* fix: failing test

* chore: bring back status expression
  • Loading branch information
adityathebe committed Aug 16, 2024
1 parent 6cf7c90 commit 28312da
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 11 deletions.
8 changes: 8 additions & 0 deletions job/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"container/ring"
gocontext "context"
"fmt"
"strconv"
"sync"
"time"

Expand Down Expand Up @@ -476,11 +477,18 @@ func (j *Job) GetResourcedName() string {

func (j *Job) AddToScheduler(cronRunner *cron.Cron) error {
cronRunner.Start()

schedule := j.Schedule
if override, ok := j.GetProperty("schedule"); ok {
schedule = override
}

if override, ok := j.GetProperty("runNow"); ok {
if parsed, err := strconv.ParseBool(override); err == nil {
j.RunNow = parsed
}
}

if schedule == "" {
return fmt.Errorf("job schedule cannot be empty")
}
Expand Down
31 changes: 26 additions & 5 deletions models/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,14 @@ type Component struct {
// ConfigID is the id of the config from which this component is derived
ConfigID *uuid.UUID `json:"config_id,omitempty"`

// statusExpr allows defining a cel expression to evaluate the status of a component
// based on the summary and the related config
// StatusExpr allows defining a cel expression to evaluate the status of a component
// based on the summary.
StatusExpr string `json:"status_expr,omitempty" gorm:"column:status_expr;default:null"`

// HealthExpr allows defining a cel expression to evaluate the health of a component
// based on the summary.
HealthExpr string `json:"health_expr,omitempty" gorm:"column:health_expr;default:null"`

// Auxiliary fields
Checks map[string]int `json:"checks,omitempty" gorm:"-"`
Incidents map[string]map[string]int `json:"incidents,omitempty" gorm:"-"`
Expand Down Expand Up @@ -163,12 +167,28 @@ func (c Component) GetStatus() (string, error) {
env := map[string]any{
"summary": c.Summary.AsEnv(),
}
statusOut, err := gomplate.RunTemplate(env, gomplate.Template{Expression: c.StatusExpr})
out, err := gomplate.RunTemplate(env, gomplate.Template{Expression: c.StatusExpr})
if err != nil {
return "", fmt.Errorf("failed to evaluate status expression %s: %v", c.StatusExpr, err)
}

return statusOut, nil
return out, nil
}

return string(c.Status), nil
}

func (c Component) GetHealth() (string, error) {
if c.HealthExpr != "" {
env := map[string]any{
"summary": c.Summary.AsEnv(),
}
out, err := gomplate.RunTemplate(env, gomplate.Template{Expression: c.HealthExpr})
if err != nil {
return "", fmt.Errorf("failed to evaluate health expression %s: %v", c.HealthExpr, err)
}

return out, nil
}

if c.Summary.Healthy > 0 && c.Summary.Unhealthy > 0 {
Expand Down Expand Up @@ -253,8 +273,9 @@ func (component Component) Clone() Component {
Properties: component.Properties,
ExternalId: component.ExternalId,
Schedule: component.Schedule,
StatusExpr: component.StatusExpr,
Health: component.Health,
StatusExpr: component.StatusExpr,
HealthExpr: component.HealthExpr,
}

copy(clone.LogSelectors, component.LogSelectors)
Expand Down
13 changes: 9 additions & 4 deletions query/topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (opt TopologyOptions) selectClause() string {
}

// parents & (incidents, analysis, checks) columns need to fetched to create the topology tree even though they may not be essential to the UI.
return "name, namespace, id, is_leaf, status, status_expr, status_reason, icon, summary, topology_type, labels, team_names, type, parent_id, parents, incidents, analysis, checks"
return "name, namespace, id, is_leaf, status, status_expr, health_expr, status_reason, icon, summary, topology_type, labels, team_names, type, parent_id, parents, incidents, analysis, checks"
}

func (opt TopologyOptions) componentWhereClause() string {
Expand Down Expand Up @@ -392,12 +392,17 @@ func generateTree(components models.Components, compChildrenMap map[string]model
// which dereferences pointer cycles
c.Summary = c.Summarize(10)

status, err := c.GetStatus()
if err != nil {
if health, err := c.GetHealth(); err != nil {
return nil, err
} else {
c.Health = lo.ToPtr(models.Health(health))
}

c.Status = types.ComponentStatus(status)
if status, err := c.GetStatus(); err != nil {
return nil, err
} else {
c.Status = types.ComponentStatus(status)
}

nodes = append(nodes, c)
}
Expand Down
8 changes: 6 additions & 2 deletions schema/components.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ table "components" {
null = true
type = text
}
column "health_expr" {
null = true
type = text
}
column "health" {
null = true
type = text
Expand Down Expand Up @@ -366,9 +370,9 @@ table "components" {
}
index "components_path_is_pushed_idx" {
on {
expr = "length(path)"
expr = "length(path)"
}
where = "is_pushed IS FALSE"
where = "is_pushed IS FALSE"
}
index "idx_components_deleted_at" {
columns = [column.deleted_at]
Expand Down
4 changes: 4 additions & 0 deletions tests/config_relationship_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,10 @@ var _ = ginkgo.Describe("Config relationship Kubernetes", ginkgo.Ordered, func()

})

ginkgo.AfterAll(func() {
Expect(DefaultContext.DB().Exec("DELETE FROM config_items WHERE tags->>'namespace' = ?", "test-related-ids").Error).To(BeNil())
})

ginkgo.It("should return deployment outgoing", func() {
relatedConfigs, err := query.GetRelatedConfigs(DefaultContext, query.RelationQuery{ID: deployment.ID, Relation: query.Outgoing})

Expand Down
1 change: 1 addition & 0 deletions views/013_check_summary.sql
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
DROP FUNCTION IF EXISTS check_summary_for_component;
DROP VIEW IF EXISTS check_summary_for_config;
DROP VIEW IF EXISTS check_summary;
DROP MATERIALIZED VIEW IF EXISTS check_status_summary;

Expand Down

0 comments on commit 28312da

Please sign in to comment.