Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't run display templates & test if the check didn't pass #1813

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions api/context/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ func (ctx *Context) GetContextualFunctions() map[string]any {
if result, ok := ctx.cache["last_result"]; ok {
return result
}
var status map[string]any

if checkID == "" {
return status
return nil
}

if ctx.DB() == nil {
logger.Errorf("[last_result] db connection not initialized")
return status
return nil
}

type CheckStatus struct {
Expand All @@ -48,10 +46,10 @@ func (ctx *Context) GetContextualFunctions() map[string]any {
Order("time DESC").Limit(1).Scan(&checkStatus).Error
if err != nil {
logger.Warnf("[last_result] failed => %s", err)
return status
return nil
}

status = map[string]any{
lastResult := map[string]any{
"status": checkStatus.Status,
"invalid": checkStatus.Invalid,
"createdAt": checkStatus.CreatedAt,
Expand All @@ -64,15 +62,15 @@ func (ctx *Context) GetContextualFunctions() map[string]any {
if checkStatus.Details != "" {
var details = make(map[string]any)
if err := json.Unmarshal([]byte(checkStatus.Details), &details); err == nil {
status["results"] = details
lastResult["results"] = details
} else {
if ctx.IsTrace() {
ctx.Warnf("[last_result] Failed to unmarshal results: %s", err.Error())
}
}
}
ctx.cache["last_result"] = status
return status
ctx.cache["last_result"] = lastResult
return lastResult
}
}
return funcs
Expand Down
7 changes: 3 additions & 4 deletions checks/alertmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ func (c *AlertManagerChecker) Check(ctx *context.Context, extConfig external.Che

connection, err := ctx.GetConnection(check.Connection)
if err != nil {
return results.Failf("error getting connection: %v", err)
return results.Errorf("error getting connection: %v", err)
}

parsedURL, err := url.Parse(connection.URL)
if err != nil {
return results.Failf("error parsing url: %v", err)
return results.Errorf("error parsing url: %v", err)
}
client := alertmanagerClient.NewHTTPClientWithConfig(nil, &alertmanagerClient.TransportConfig{
Host: parsedURL.Host,
Expand All @@ -67,8 +67,7 @@ func (c *AlertManagerChecker) Check(ctx *context.Context, extConfig external.Che
Filter: filters,
})
if err != nil {
results.ErrorMessage(fmt.Errorf("Error fetching from alertmanager: %v", err))
return results
return results.Errorf("error fetching from alertmanager: %v", err)
}

type Alerts struct {
Expand Down
8 changes: 4 additions & 4 deletions checks/aws_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ func (c *AwsConfigChecker) Check(ctx *context.Context, extConfig external.Check)
check.AWSConnection = &connection.AWSConnection{}
} else {
if err := check.AWSConnection.Populate(ctx); err != nil {
return results.Failf("failed to populate aws connection: %v", err)
return results.Errorf("failed to populate aws connection: %v", err)
}
}

cfg, err := awsUtil.NewSession(ctx.Context, *check.AWSConnection)
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}

client := configservice.NewFromConfig(*cfg)
Expand All @@ -56,15 +56,15 @@ func (c *AwsConfigChecker) Check(ctx *context.Context, extConfig external.Check)
Expression: &check.Query,
})
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}
result.AddDetails(output.Results)
} else {
output, err := client.SelectResourceConfig(ctx, &configservice.SelectResourceConfigInput{
Expression: &check.Query,
})
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}
result.AddDetails(output.Results)
}
Expand Down
10 changes: 3 additions & 7 deletions checks/aws_config_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,15 @@ func (c *AwsConfigRuleChecker) Check(ctx *context.Context, extConfig external.Ch
if check.AWSConnection == nil {
check.AWSConnection = &connection.AWSConnection{}
} else if err := check.AWSConnection.Populate(ctx); err != nil {
return results.Failf("failed to populate aws connection: %v", err)
return results.Errorf("failed to populate aws connection: %v", err)
}

cfg, err := awsUtil.NewSession(ctx.Context, *check.AWSConnection)
if err != nil {
return results.Failf("failed to create a session: %v", err)
return results.Errorf("failed to create a session: %v", err)
}

client := configservice.NewFromConfig(*cfg)
if err != nil {
return results.Failf("failed to describe compliance rules: %v", err)
}

var complianceTypes = []types.ComplianceType{}
for _, i := range check.ComplianceTypes {
complianceTypes = append(complianceTypes, types.ComplianceType(i))
Expand All @@ -64,7 +60,7 @@ func (c *AwsConfigRuleChecker) Check(ctx *context.Context, extConfig external.Ch
ConfigRuleNames: check.Rules,
})
if err != nil {
return results.Failf("failed to describe compliance rules: %v", err)
return results.Errorf("failed to describe compliance rules: %v", err)
}

type ConfigRuleResource struct {
Expand Down
14 changes: 7 additions & 7 deletions checks/azure_devops.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,22 @@ func (t *AzureDevopsChecker) check(ctx *context.Context, check v1.AzureDevopsChe
if check.PersonalAccessToken.ValueStatic != "" {
c = &models.Connection{Password: check.PersonalAccessToken.ValueStatic}
} else if c, err = ctx.HydrateConnectionByURL(check.ConnectionName); err != nil {
return results.Failf("failed to hydrate connection: %v", err)
return results.Errorf("failed to hydrate connection: %v", err)
} else if c != nil {
if c, err = c.Merge(ctx, check); err != nil {
return results.Failf("failed to merge connection: %v", err)
return results.Errorf("failed to merge connection: %v", err)
}
}

connection := azuredevops.NewPatConnection(fmt.Sprintf("https://dev.azure.com/%s", check.Organization), c.Password)
coreClient, err := core.NewClient(ctx, connection)
if err != nil {
return results.ErrorMessage(fmt.Errorf("failed to create core client: %w", err))
return results.Errorf("failed to create core client: %v", err)
}

project, err := coreClient.GetProject(ctx, core.GetProjectArgs{ProjectId: &check.Project})
if err != nil {
return results.ErrorMessage(fmt.Errorf("failed to get project (name=%s): %w", check.Project, err))
return results.Errorf("failed to get project (name=%s): %v", check.Project, err)
}
projectID := project.Id.String()

Expand All @@ -68,7 +68,7 @@ func (t *AzureDevopsChecker) check(ctx *context.Context, check v1.AzureDevopsChe
pipelineClient := pipelines.NewClient(ctx, connection)
allPipelines, err := pipelineClient.ListPipelines(ctx, pipelines.ListPipelinesArgs{Project: &projectID})
if err != nil {
return results.ErrorMessage(fmt.Errorf("failed to get pipeline (project=%s): %w", check.Project, err))
return results.Errorf("failed to get pipeline (project=%s): %v", check.Project, err)
}

for _, pipeline := range *allPipelines {
Expand All @@ -89,7 +89,7 @@ func (t *AzureDevopsChecker) check(ctx *context.Context, check v1.AzureDevopsChe
// https://learn.microsoft.com/en-us/rest/api/azure/devops/pipelines/runs/list?view=azure-devops-rest-7.1
runs, err := pipelineClient.ListRuns(ctx, pipelines.ListRunsArgs{PipelineId: pipeline.Id, Project: &projectID})
if err != nil {
return results.ErrorMessage(fmt.Errorf("failed to get runs (pipeline=%s): %w", check.Pipeline, err))
return results.Errorf("failed to get runs (pipeline=%s): %v", check.Pipeline, err)
}

latestRun := getLatestCompletedRun(*runs)
Expand All @@ -105,7 +105,7 @@ func (t *AzureDevopsChecker) check(ctx *context.Context, check v1.AzureDevopsChe
// because the ListRuns API doesn't return Resources.
latestRun, err = pipelineClient.GetRun(ctx, pipelines.GetRunArgs{Project: &projectID, PipelineId: pipeline.Id, RunId: (*runs)[0].Id})
if err != nil {
return results.ErrorMessage(fmt.Errorf("failed to get run (pipeline=%s): %w", check.Pipeline, err))
return results.Errorf("failed to get run (pipeline=%s): %v", check.Pipeline, err)
}

if !matchBranchNames(check.Branches, latestRun.Resources) {
Expand Down
2 changes: 1 addition & 1 deletion checks/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (c *CatalogChecker) Check(ctx *canaryContext.Context, check v1.CatalogCheck

items, err := query.FindConfigsByResourceSelector(ctx.Context, check.Selector...)
if err != nil {
return results.Failf("failed to fetch catalogs: %v", err)
return results.Errorf("failed to fetch catalogs: %v", err)
}

var configItems []map[string]any
Expand Down
8 changes: 4 additions & 4 deletions checks/cloudwatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ func (c *CloudWatchChecker) Check(ctx *context.Context, extConfig external.Check
results = append(results, result)

if err := check.AWSConnection.Populate(ctx); err != nil {
return results.Failf("failed to populate aws connection: %v", err)
return results.Errorf("failed to populate aws connection: %v", err)
}

cfg, err := awsUtil.NewSession(ctx.Context, check.AWSConnection)
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}
client := cloudwatch.NewFromConfig(*cfg)
maxRecords := int32(100)
Expand All @@ -56,10 +56,10 @@ func (c *CloudWatchChecker) Check(ctx *context.Context, extConfig external.Check
MaxRecords: &maxRecords,
})
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}
if o, err := unstructure(alarms); err != nil {
return results.ErrorMessage(err)
return results.Error(err)
} else {
result.AddDetails(o)
}
Expand Down
3 changes: 1 addition & 2 deletions checks/database_backup.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package checks

import (
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"

"github.com/flanksource/canary-checker/api/context"
Expand Down Expand Up @@ -60,5 +59,5 @@ func FailDatabaseBackupParse(ctx *context.Context, check v1.DatabaseBackupCheck)
result := pkg.Fail(check, ctx.Canary)
var results pkg.Results
results = append(results, result)
return results.ErrorMessage(errors.New("Could not parse databaseBackup input"))
return results.Errorf("Could not parse databaseBackup input")
}
9 changes: 4 additions & 5 deletions checks/database_backup_gcp.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package checks

import (
"errors"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -30,21 +29,21 @@ func GCPDatabaseBackupCheck(ctx *context.Context, check v1.DatabaseBackupCheck)
results = append(results, result)

if err := check.GCP.HydrateConnection(ctx); err != nil {
return results.Failf("failed to populate GCP connection: %v", err)
return results.Errorf("failed to populate GCP connection: %v", err)
}

svc, err := gcp.NewSQLAdmin(ctx.Context, check.GCP.GCPConnection)
if err != nil {
databaseScanFailCount.WithLabelValues(check.GCP.Project, check.GCP.Instance).Inc()
return results.ErrorMessage(err)
return results.Error(err)
}

// Only checking one backup for now, but setting up the logic that this could maybe be configurable.
// Would need some extra parsing on the age to select latest
backupList, err := svc.BackupRuns.List(check.GCP.Project, check.GCP.Instance).MaxResults(1).Do()
if err != nil {
databaseScanFailCount.WithLabelValues(check.GCP.Project, check.GCP.Instance).Inc()
return results.ErrorMessage(err)
return results.Error(err)
}
var errorMessages []string
for _, backup := range backupList.Items {
Expand Down Expand Up @@ -103,7 +102,7 @@ func GCPDatabaseBackupCheck(ctx *context.Context, check v1.DatabaseBackupCheck)
}
if len(errorMessages) > 0 {
databaseScanFailCount.WithLabelValues(check.GCP.Project, check.GCP.Instance).Inc()
return results.ErrorMessage(errors.New(strings.Join(errorMessages, ", ")))
return results.Errorf(strings.Join(errorMessages, ", "))
}

backupRaw, err := backupList.Items[0].MarshalJSON()
Expand Down
4 changes: 2 additions & 2 deletions checks/dns.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (c *DNSChecker) Check(ctx *canaryContext.Context, extConfig external.Check)
if check.Server != "" {
dialer, err := getDialer(check, timeout)
if err != nil {
return results.Failf("Failed to get dialer, %v", err)
return results.Errorf("Failed to get dialer, %v", err)
}
r = net.Resolver{
PreferGo: true,
Expand All @@ -71,7 +71,7 @@ func (c *DNSChecker) Check(ctx *canaryContext.Context, extConfig external.Check)

resultCh := make(chan *pkg.CheckResult, 1)
if fn, ok := resolvers[strings.ToUpper(queryType)]; !ok {
return results.Failf("unknown query type: %s", queryType)
return results.Errorf("unknown query type: %s", queryType)
} else {
go func() {
pass, message, err := fn(ctx, &r, check)
Expand Down
4 changes: 2 additions & 2 deletions checks/dynatrace.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (t *DynatraceChecker) Check(ctx *context.Context, extConfig external.Check)

apiKey, err := ctx.GetEnvValueFromCache(check.APIKey)
if err != nil {
return results.Failf("error getting Dynatrace API key: %v", err)
return results.Errorf("error getting Dynatrace API key: %v", err)
}

config := dynatrace.NewConfiguration()
Expand All @@ -46,7 +46,7 @@ func (t *DynatraceChecker) Check(ctx *context.Context, extConfig external.Check)
apiClient := dynatrace.NewAPIClient(config)
problems, apiResponse, err := apiClient.ProblemsApi.GetProblems(ctx).Execute()
if err != nil {
return results.Failf("error getting Dynatrace problems: %s", err.Error())
return results.Errorf("error getting Dynatrace problems: %s", err.Error())
}
defer apiResponse.Body.Close()

Expand Down
19 changes: 7 additions & 12 deletions checks/elasticsearch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package checks

import (
"encoding/json"
"fmt"
"strings"

"github.com/flanksource/canary-checker/api/context"
Expand Down Expand Up @@ -36,7 +35,7 @@ func (c *ElasticsearchChecker) Check(ctx *context.Context, extConfig external.Ch

connection, err := ctx.GetConnection(check.Connection)
if err != nil {
return results.Failf("error getting connection: %v", err)
return results.Errorf("error getting connection: %v", err)
}

cfg := elasticsearch.Config{
Expand All @@ -47,7 +46,7 @@ func (c *ElasticsearchChecker) Check(ctx *context.Context, extConfig external.Ch

es, err := elasticsearch.NewClient(cfg)
if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}

body := strings.NewReader(check.Query)
Expand All @@ -58,21 +57,19 @@ func (c *ElasticsearchChecker) Check(ctx *context.Context, extConfig external.Ch
)

if err != nil {
return results.ErrorMessage(err)
return results.Error(err)
}

if res.IsError() {
var e map[string]any
if err := json.NewDecoder(res.Body).Decode(&e); err != nil {
return results.ErrorMessage(
fmt.Errorf("Error parsing the response body: %s", err),
)
return results.Errorf("error parsing the response body: %s", err)
} else {
return results.ErrorMessage(fmt.Errorf("Error from elasticsearch [%s]: %v, %v",
return results.Errorf("error from elasticsearch [%s]: %v, %v",
res.Status(),
e["error"].(map[string]any)["type"],
e["error"].(map[string]any)["reason"],
))
)
}
}

Expand All @@ -81,9 +78,7 @@ func (c *ElasticsearchChecker) Check(ctx *context.Context, extConfig external.Ch
defer res.Body.Close()
var r map[string]any
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
return results.ErrorMessage(
fmt.Errorf("Error parsing the response body: %s", err),
)
return results.Errorf("Error parsing the response body: %s", err)
}

count := int(r["hits"].(map[string]any)["total"].(map[string]any)["value"].(float64))
Expand Down
Loading
Loading