diff --git a/observability-lib/cmd/builder.go b/observability-lib/cmd/builder.go index f7a5e8c23..4be5289e2 100644 --- a/observability-lib/cmd/builder.go +++ b/observability-lib/cmd/builder.go @@ -46,7 +46,7 @@ type BuildOptions struct { AlertsFilters string } -func BuildDashboardWithType(options *BuildOptions) (*grafana.Dashboard, error) { +func BuildDashboardWithType(options *BuildOptions) (*grafana.Observability, error) { switch options.TypeDashboard { case TypeDashboardCoreNode: return corenode.NewDashboard(&corenode.Props{ diff --git a/observability-lib/dashboards/atlas-don/component.go b/observability-lib/dashboards/atlas-don/component.go index 235122e15..098bda871 100644 --- a/observability-lib/dashboards/atlas-don/component.go +++ b/observability-lib/dashboards/atlas-don/component.go @@ -10,7 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/observability-lib/grafana" ) -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/atlas-don/component_test.go b/observability-lib/dashboards/atlas-don/component_test.go index 02c87ca7c..7ce5bb775 100644 --- a/observability-lib/dashboards/atlas-don/component_test.go +++ b/observability-lib/dashboards/atlas-don/component_test.go @@ -64,7 +64,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "DON OCR Dashboard", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/dashboards/capabilities/component.go b/observability-lib/dashboards/capabilities/component.go index 27c035c97..9c36d9be7 100644 --- a/observability-lib/dashboards/capabilities/component.go +++ b/observability-lib/dashboards/capabilities/component.go @@ -15,7 +15,7 @@ type Props struct { } // NewDashboard creates a Capabilities dashboard -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/capabilities/component_test.go b/observability-lib/dashboards/capabilities/component_test.go index f42080889..90ad5ce9e 100644 --- a/observability-lib/dashboards/capabilities/component_test.go +++ b/observability-lib/dashboards/capabilities/component_test.go @@ -60,7 +60,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "Capabilities Dashboard", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/dashboards/core-node-components/component.go b/observability-lib/dashboards/core-node-components/component.go index f581136e6..6175fd438 100644 --- a/observability-lib/dashboards/core-node-components/component.go +++ b/observability-lib/dashboards/core-node-components/component.go @@ -9,7 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-common/observability-lib/grafana" ) -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/core-node-components/component_test.go b/observability-lib/dashboards/core-node-components/component_test.go index 57d3219fa..ce257164c 100644 --- a/observability-lib/dashboards/core-node-components/component_test.go +++ b/observability-lib/dashboards/core-node-components/component_test.go @@ -64,7 +64,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "Core Node Components Dashboard", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/dashboards/core-node/component.go b/observability-lib/dashboards/core-node/component.go index 1843b4003..8374bad53 100644 --- a/observability-lib/dashboards/core-node/component.go +++ b/observability-lib/dashboards/core-node/component.go @@ -14,7 +14,7 @@ import ( ) // NewDashboard creates a DON dashboard for the given OCR version -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/core-node/component_test.go b/observability-lib/dashboards/core-node/component_test.go index 787160c30..965acc493 100644 --- a/observability-lib/dashboards/core-node/component_test.go +++ b/observability-lib/dashboards/core-node/component_test.go @@ -65,7 +65,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "Core Node Dashboard", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/dashboards/k8s-resources/component.go b/observability-lib/dashboards/k8s-resources/component.go index 1268113a7..2e3b19d9e 100644 --- a/observability-lib/dashboards/k8s-resources/component.go +++ b/observability-lib/dashboards/k8s-resources/component.go @@ -15,7 +15,7 @@ type Props struct { MetricsDataSource *grafana.DataSource // MetricsDataSource is the datasource for querying metrics } -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/k8s-resources/component_test.go b/observability-lib/dashboards/k8s-resources/component_test.go index 466bbe175..a32c7cda6 100644 --- a/observability-lib/dashboards/k8s-resources/component_test.go +++ b/observability-lib/dashboards/k8s-resources/component_test.go @@ -58,7 +58,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "K8s resources", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/dashboards/nop-ocr/component.go b/observability-lib/dashboards/nop-ocr/component.go index 2c58a40ce..9978c5f73 100644 --- a/observability-lib/dashboards/nop-ocr/component.go +++ b/observability-lib/dashboards/nop-ocr/component.go @@ -16,7 +16,7 @@ type Props struct { OCRVersion string // OCRVersion is the version of the OCR (ocr, ocr2, ocr3) } -func NewDashboard(props *Props) (*grafana.Dashboard, error) { +func NewDashboard(props *Props) (*grafana.Observability, error) { if props.Name == "" { return nil, fmt.Errorf("Name is required") } diff --git a/observability-lib/dashboards/nop-ocr/component_test.go b/observability-lib/dashboards/nop-ocr/component_test.go index b68469526..cfa4009a3 100644 --- a/observability-lib/dashboards/nop-ocr/component_test.go +++ b/observability-lib/dashboards/nop-ocr/component_test.go @@ -59,7 +59,7 @@ func TestNewDashboard(t *testing.T) { if err != nil { t.Errorf("Error creating dashboard: %v", err) } - require.IsType(t, grafana.Dashboard{}, *testDashboard) + require.IsType(t, grafana.Observability{}, *testDashboard) require.Equal(t, "NOP OCR Dashboard", *testDashboard.Dashboard.Title) json, errJSON := testDashboard.GenerateJSON() if errJSON != nil { diff --git a/observability-lib/grafana/builder.go b/observability-lib/grafana/builder.go index 7b4aba40a..10d5813c9 100644 --- a/observability-lib/grafana/builder.go +++ b/observability-lib/grafana/builder.go @@ -29,16 +29,23 @@ type BuilderOptions struct { } func NewBuilder(options *BuilderOptions) *Builder { - if options.TimeZone == "" { - options.TimeZone = common.TimeZoneBrowser - } + builder := &Builder{} - builder := &Builder{ - dashboardBuilder: dashboard.NewDashboardBuilder(options.Name). - Tags(options.Tags). - Refresh(options.Refresh). - Time(options.TimeFrom, options.TimeTo). - Timezone(options.TimeZone), + if options.Name != "" { + builder.dashboardBuilder = dashboard.NewDashboardBuilder(options.Name) + if options.Tags != nil { + builder.dashboardBuilder.Tags(options.Tags) + } + if options.Refresh != "" { + builder.dashboardBuilder.Refresh(options.Refresh) + } + if options.TimeFrom != "" && options.TimeTo != "" { + builder.dashboardBuilder.Time(options.TimeFrom, options.TimeTo) + } + if options.TimeZone == "" { + options.TimeZone = common.TimeZoneBrowser + } + builder.dashboardBuilder.Timezone(options.TimeZone) } if options.AlertsTags != nil { @@ -104,33 +111,39 @@ func (b *Builder) AddNotificationPolicy(notificationPolicies ...*alerting.Notifi b.notificationPoliciesBuilder = append(b.notificationPoliciesBuilder, notificationPolicies...) } -func (b *Builder) Build() (*Dashboard, error) { - db, errBuildDashboard := b.dashboardBuilder.Build() - if errBuildDashboard != nil { - return nil, errBuildDashboard - } +func (b *Builder) Build() (*Observability, error) { + observability := Observability{} - var alerts []alerting.Rule - for _, alertBuilder := range b.alertsBuilder { - alert, errBuildAlert := alertBuilder.Build() - if errBuildAlert != nil { - return nil, errBuildAlert + if b.dashboardBuilder != nil { + db, errBuildDashboard := b.dashboardBuilder.Build() + if errBuildDashboard != nil { + return nil, errBuildDashboard } + observability.Dashboard = &db - // Add common tags to alerts - if b.alertsTags != nil && len(b.alertsTags) > 0 { - tags := maps.Clone(b.alertsTags) - maps.Copy(tags, alert.Labels) + var alerts []alerting.Rule + for _, alertBuilder := range b.alertsBuilder { + alert, errBuildAlert := alertBuilder.Build() + if errBuildAlert != nil { + return nil, errBuildAlert + } - alertBuildWithTags := alertBuilder.Labels(tags) - alertWithTags, errBuildAlertWithTags := alertBuildWithTags.Build() - if errBuildAlertWithTags != nil { - return nil, errBuildAlertWithTags + // Add common tags to alerts + if b.alertsTags != nil && len(b.alertsTags) > 0 { + tags := maps.Clone(b.alertsTags) + maps.Copy(tags, alert.Labels) + + alertBuildWithTags := alertBuilder.Labels(tags) + alertWithTags, errBuildAlertWithTags := alertBuildWithTags.Build() + if errBuildAlertWithTags != nil { + return nil, errBuildAlertWithTags + } + alerts = append(alerts, alertWithTags) + } else { + alerts = append(alerts, alert) } - alerts = append(alerts, alertWithTags) - } else { - alerts = append(alerts, alert) } + observability.Alerts = alerts } var contactPoints []alerting.ContactPoint @@ -141,6 +154,7 @@ func (b *Builder) Build() (*Dashboard, error) { } contactPoints = append(contactPoints, contactPoint) } + observability.ContactPoints = contactPoints var notificationPolicies []alerting.NotificationPolicy for _, notificationPolicyBuilder := range b.notificationPoliciesBuilder { @@ -150,11 +164,7 @@ func (b *Builder) Build() (*Dashboard, error) { } notificationPolicies = append(notificationPolicies, notificationPolicy) } + observability.NotificationPolicies = notificationPolicies - return &Dashboard{ - Dashboard: &db, - Alerts: alerts, - ContactPoints: contactPoints, - NotificationPolicies: notificationPolicies, - }, nil + return &observability, nil } diff --git a/observability-lib/grafana/builder_test.go b/observability-lib/grafana/builder_test.go index 003072176..e31db74de 100644 --- a/observability-lib/grafana/builder_test.go +++ b/observability-lib/grafana/builder_test.go @@ -3,6 +3,7 @@ package grafana_test import ( "testing" + "github.com/grafana/grafana-foundation-sdk/go/alerting" "github.com/stretchr/testify/require" "github.com/grafana/grafana-foundation-sdk/go/dashboard" @@ -21,18 +22,86 @@ func TestNewBuilder(t *testing.T) { TimeZone: "UTC", }) - db, err := builder.Build() + o, err := builder.Build() if err != nil { - t.Errorf("Error building dashboard: %v", err) + t.Errorf("Error during build: %v", err) + } + + require.NotEmpty(t, o.Dashboard) + require.Empty(t, o.Alerts) + require.Empty(t, o.ContactPoints) + require.Empty(t, o.NotificationPolicies) + }) + + t.Run("NewBuilder builds a dashboard with alerts", func(t *testing.T) { + builder := grafana.NewBuilder(&grafana.BuilderOptions{ + Name: "Dashboard Name", + Tags: []string{"foo", "bar"}, + Refresh: "1m", + TimeFrom: "now-1h", + TimeTo: "now", + TimeZone: "UTC", + }) + builder.AddAlert(grafana.NewAlertRule(&grafana.AlertOptions{ + Title: "Alert Title", + })) + + o, err := builder.Build() + if err != nil { + t.Errorf("Error during build: %v", err) } - require.IsType(t, dashboard.Dashboard{}, *db.Dashboard) + require.NotEmpty(t, o.Dashboard) + require.NotEmpty(t, o.Alerts) + require.Empty(t, o.ContactPoints) + require.Empty(t, o.NotificationPolicies) + }) + + t.Run("NewBuilder builds a contact point", func(t *testing.T) { + builder := grafana.NewBuilder(&grafana.BuilderOptions{}) + builder.AddContactPoint(grafana.NewContactPoint(&grafana.ContactPointOptions{ + Name: "slack", + Type: "slack", + })) + + o, err := builder.Build() + if err != nil { + t.Errorf("Error during build: %v", err) + } + + require.Empty(t, o.Dashboard) + require.Empty(t, o.Alerts) + require.NotEmpty(t, o.ContactPoints) + require.Empty(t, o.NotificationPolicies) + }) + + t.Run("NewBuilder builds a notification policy", func(t *testing.T) { + builder := grafana.NewBuilder(&grafana.BuilderOptions{}) + builder.AddNotificationPolicy(grafana.NewNotificationPolicy(&grafana.NotificationPolicyOptions{ + Receiver: "slack", + GroupBy: []string{"grafana_folder", "alertname"}, + ObjectMatchers: []alerting.ObjectMatcher{ + {"team", "=", "chainlink"}, + }, + })) + + o, err := builder.Build() + if err != nil { + t.Errorf("Error during build: %v", err) + } + + require.Empty(t, o.Dashboard) + require.Empty(t, o.Alerts) + require.Empty(t, o.ContactPoints) + require.NotEmpty(t, o.NotificationPolicies) }) } func TestBuilder_AddVars(t *testing.T) { t.Run("AddVars adds variables to the dashboard", func(t *testing.T) { - builder := grafana.NewBuilder(&grafana.BuilderOptions{}) + builder := grafana.NewBuilder(&grafana.BuilderOptions{ + Name: "Dashboard Name", + }) variable := grafana.NewQueryVariable(&grafana.QueryVariableOptions{ VariableOption: &grafana.VariableOption{ @@ -44,30 +113,34 @@ func TestBuilder_AddVars(t *testing.T) { }) builder.AddVars(variable) - db, err := builder.Build() + o, err := builder.Build() if err != nil { t.Errorf("Error building dashboard: %v", err) } - require.IsType(t, dashboard.Dashboard{}, *db.Dashboard) + require.Len(t, o.Dashboard.Templating.List, 1) }) } func TestBuilder_AddRow(t *testing.T) { t.Run("AddRow adds a row to the dashboard", func(t *testing.T) { - builder := grafana.NewBuilder(&grafana.BuilderOptions{}) + builder := grafana.NewBuilder(&grafana.BuilderOptions{ + Name: "Dashboard Name", + }) builder.AddRow("Row Title") - db, err := builder.Build() + o, err := builder.Build() if err != nil { t.Errorf("Error building dashboard: %v", err) } - require.IsType(t, dashboard.Dashboard{}, *db.Dashboard) + require.IsType(t, dashboard.RowPanel{}, *o.Dashboard.Panels[0].RowPanel) }) } func TestBuilder_AddPanel(t *testing.T) { t.Run("AddPanel adds a panel to the dashboard", func(t *testing.T) { - builder := grafana.NewBuilder(&grafana.BuilderOptions{}) + builder := grafana.NewBuilder(&grafana.BuilderOptions{ + Name: "Dashboard Name", + }) panel := grafana.NewStatPanel(&grafana.StatPanelOptions{ PanelOptions: &grafana.PanelOptions{ @@ -76,10 +149,10 @@ func TestBuilder_AddPanel(t *testing.T) { }) builder.AddPanel(panel) - db, err := builder.Build() + o, err := builder.Build() if err != nil { t.Errorf("Error building dashboard: %v", err) } - require.IsType(t, dashboard.Dashboard{}, *db.Dashboard) + require.IsType(t, dashboard.Panel{}, *o.Dashboard.Panels[0].Panel) }) } diff --git a/observability-lib/grafana/dashboard.go b/observability-lib/grafana/dashboard.go index 8b2119a7c..a9b31fa59 100644 --- a/observability-lib/grafana/dashboard.go +++ b/observability-lib/grafana/dashboard.go @@ -17,20 +17,20 @@ const ( TypePlatformDocker TypePlatform = "docker" ) -type Dashboard struct { +type Observability struct { Dashboard *dashboard.Dashboard Alerts []alerting.Rule ContactPoints []alerting.ContactPoint NotificationPolicies []alerting.NotificationPolicy } -func (db *Dashboard) GenerateJSON() ([]byte, error) { - dashboardJSON, err := json.MarshalIndent(db, "", " ") +func (o *Observability) GenerateJSON() ([]byte, error) { + output, err := json.MarshalIndent(o, "", " ") if err != nil { return nil, err } - return dashboardJSON, nil + return output, nil } type DeployOptions struct { @@ -59,38 +59,35 @@ func getAlertRuleByTitle(alerts []alerting.Rule, title string) *alerting.Rule { return nil } -func (db *Dashboard) DeployToGrafana(options *DeployOptions) error { +func (o *Observability) DeployToGrafana(options *DeployOptions) error { grafanaClient := api.NewClient( options.GrafanaURL, options.GrafanaToken, ) - folder, errFolder := grafanaClient.FindOrCreateFolder(options.FolderName) - if errFolder != nil { - return errFolder - } - - newDashboard, _, errPostDashboard := grafanaClient.PostDashboard(api.PostDashboardRequest{ - Dashboard: db.Dashboard, - Overwrite: true, - FolderID: int(folder.ID), - }) - if errPostDashboard != nil { - return errPostDashboard - } - - // Create alerts for the dashboard - if options.EnableAlerts && db.Alerts != nil && len(db.Alerts) > 0 { - // Get alert rules for the dashboard - alertsRule, errGetAlertRules := grafanaClient.GetAlertRulesByDashboardUID(*newDashboard.UID) - if errGetAlertRules != nil { - return errGetAlertRules + if options.FolderName != "" { + folder, errFolder := grafanaClient.FindOrCreateFolder(options.FolderName) + if errFolder != nil { + return errFolder } + newDashboard, _, errPostDashboard := grafanaClient.PostDashboard(api.PostDashboardRequest{ + Dashboard: o.Dashboard, + Overwrite: true, + FolderID: int(folder.ID), + }) + if errPostDashboard != nil { + return errPostDashboard + } + + if !options.EnableAlerts && o.Alerts != nil && len(o.Alerts) > 0 { + // Get alert rules for the dashboard + alertsRule, errGetAlertRules := grafanaClient.GetAlertRulesByDashboardUID(*newDashboard.UID) + if errGetAlertRules != nil { + return errGetAlertRules + } - // delete alert rules for the dashboard - for _, rule := range alertsRule { - // delete alert rule only if it won't be created again from code - if !alertRuleExist(db.Alerts, rule) { + // delete existing alert rules for the dashboard if alerts are disabled + for _, rule := range alertsRule { _, _, errDeleteAlertRule := grafanaClient.DeleteAlertRule(*rule.Uid) if errDeleteAlertRule != nil { return errDeleteAlertRule @@ -98,32 +95,52 @@ func (db *Dashboard) DeployToGrafana(options *DeployOptions) error { } } - // Create alert rules for the dashboard - for _, alert := range db.Alerts { - alert.RuleGroup = *db.Dashboard.Title - alert.FolderUID = folder.UID - alert.Annotations["__dashboardUid__"] = *newDashboard.UID - - panelId := panelIDByTitle(db.Dashboard, alert.Annotations["panel_title"]) - // we can clean it up as it was only used to get the panelId - delete(alert.Annotations, "panel_title") - if panelId != "" { - alert.Annotations["__panelId__"] = panelId + // Create alerts for the dashboard + if options.EnableAlerts && o.Alerts != nil && len(o.Alerts) > 0 { + // Get alert rules for the dashboard + alertsRule, errGetAlertRules := grafanaClient.GetAlertRulesByDashboardUID(*newDashboard.UID) + if errGetAlertRules != nil { + return errGetAlertRules } - if alertRuleExist(alertsRule, alert) { - // update alert rule if it already exists - alertToUpdate := getAlertRuleByTitle(alertsRule, alert.Title) - if alertToUpdate != nil { - _, _, errPutAlertRule := grafanaClient.UpdateAlertRule(*alertToUpdate.Uid, alert) - if errPutAlertRule != nil { - return errPutAlertRule + + // delete alert rules for the dashboard + for _, rule := range alertsRule { + // delete alert rule only if it won't be created again from code + if !alertRuleExist(o.Alerts, rule) { + _, _, errDeleteAlertRule := grafanaClient.DeleteAlertRule(*rule.Uid) + if errDeleteAlertRule != nil { + return errDeleteAlertRule } } - } else { - // create alert rule if it doesn't exist - _, _, errPostAlertRule := grafanaClient.PostAlertRule(alert) - if errPostAlertRule != nil { - return errPostAlertRule + } + + // Create alert rules for the dashboard + for _, alert := range o.Alerts { + alert.RuleGroup = *o.Dashboard.Title + alert.FolderUID = folder.UID + alert.Annotations["__dashboardUid__"] = *newDashboard.UID + + panelId := panelIDByTitle(o.Dashboard, alert.Annotations["panel_title"]) + // we can clean it up as it was only used to get the panelId + delete(alert.Annotations, "panel_title") + if panelId != "" { + alert.Annotations["__panelId__"] = panelId + } + if alertRuleExist(alertsRule, alert) { + // update alert rule if it already exists + alertToUpdate := getAlertRuleByTitle(alertsRule, alert.Title) + if alertToUpdate != nil { + _, _, errPutAlertRule := grafanaClient.UpdateAlertRule(*alertToUpdate.Uid, alert) + if errPutAlertRule != nil { + return errPutAlertRule + } + } + } else { + // create alert rule if it doesn't exist + _, _, errPostAlertRule := grafanaClient.PostAlertRule(alert) + if errPostAlertRule != nil { + return errPostAlertRule + } } } } @@ -146,8 +163,8 @@ func (db *Dashboard) DeployToGrafana(options *DeployOptions) error { } // Create contact points for the alerts - if db.ContactPoints != nil && len(db.ContactPoints) > 0 { - for _, contactPoint := range db.ContactPoints { + if o.ContactPoints != nil && len(o.ContactPoints) > 0 { + for _, contactPoint := range o.ContactPoints { errCreateOrUpdateContactPoint := grafanaClient.CreateOrUpdateContactPoint(contactPoint) if errCreateOrUpdateContactPoint != nil { return errCreateOrUpdateContactPoint @@ -156,8 +173,8 @@ func (db *Dashboard) DeployToGrafana(options *DeployOptions) error { } // Create notification policies for the alerts - if db.NotificationPolicies != nil && len(db.NotificationPolicies) > 0 { - for _, notificationPolicy := range db.NotificationPolicies { + if o.NotificationPolicies != nil && len(o.NotificationPolicies) > 0 { + for _, notificationPolicy := range o.NotificationPolicies { errAddNestedPolicy := grafanaClient.AddNestedPolicy(notificationPolicy) if errAddNestedPolicy != nil { return errAddNestedPolicy diff --git a/observability-lib/grafana/dashboard_test.go b/observability-lib/grafana/dashboard_test.go index 3f0ed8bf6..ecac1d04a 100644 --- a/observability-lib/grafana/dashboard_test.go +++ b/observability-lib/grafana/dashboard_test.go @@ -66,12 +66,12 @@ func TestGenerateJSON(t *testing.T) { }, })) - db, err := builder.Build() + o, err := builder.Build() if err != nil { t.Errorf("Error building dashboard: %v", err) } - json, err := db.GenerateJSON() + json, err := o.GenerateJSON() require.IsType(t, json, []byte{}) }) }