Skip to content

Commit

Permalink
feat: webhook check (#1387)
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe authored Nov 1, 2023
1 parent 418bdd2 commit b4717c4
Show file tree
Hide file tree
Showing 31 changed files with 1,214 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ on:
- "**.yaml"
- "**.yml"
- "test/**"
name: Postgres-and-Push-Test
name: Operator E2E Test
permissions:
contents: read
jobs:
Expand All @@ -41,4 +41,4 @@ jobs:
cache-
- run: make bin
- name: Test
run: ./test/e2e-postgres-push.sh
run: ./test/e2e-operator.sh
1 change: 1 addition & 0 deletions api/v1/canary_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type CanarySpec struct {
AlertManager []AlertManagerCheck `yaml:"alertmanager,omitempty" json:"alertmanager,omitempty"`
Dynatrace []DynatraceCheck `yaml:"dynatrace,omitempty" json:"dynatrace,omitempty"`
AzureDevops []AzureDevopsCheck `yaml:"azureDevops,omitempty" json:"azureDevops,omitempty"`
Webhook *WebhookCheck `yaml:"webhook,omitempty" json:"webhook,omitempty"`
// interval (in seconds) to run checks on Deprecated in favor of Schedule
Interval uint64 `yaml:"interval,omitempty" json:"interval,omitempty"`
// Schedule to run checks on. Supports all cron expression, example: '30 3-6,20-23 * * *'. For more info about cron expression syntax see https://en.wikipedia.org/wiki/Cron
Expand Down
17 changes: 17 additions & 0 deletions api/v1/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,22 @@ func (c AzureDevopsCheck) GetEndpoint() string {
return c.Project
}

type WebhookCheck struct {
Description `yaml:",inline" json:",inline"`
Templatable `yaml:",inline" json:",inline"`

// Token is an optional authorization token to run this check
Token *types.EnvVar `yaml:"token,omitempty" json:"token,omitempty"`
}

func (c WebhookCheck) GetType() string {
return "webhook"
}

func (c WebhookCheck) GetEndpoint() string {
return ""
}

var AllChecks = []external.Check{
AlertManagerCheck{},
AwsConfigCheck{},
Expand Down Expand Up @@ -1396,4 +1412,5 @@ var AllChecks = []external.Check{
ResticCheck{},
S3Check{},
TCPCheck{},
WebhookCheck{},
}
27 changes: 27 additions & 0 deletions api/v1/zz_generated.deepcopy.go

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

33 changes: 18 additions & 15 deletions checks/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"time"

_ "github.com/robertkrimen/otto/underscore"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/flanksource/canary-checker/api/context"
v1 "github.com/flanksource/canary-checker/api/v1"
"github.com/flanksource/canary-checker/pkg"
"github.com/flanksource/canary-checker/pkg/utils"
cUtils "github.com/flanksource/commons/utils"
"github.com/flanksource/gomplate/v3"
"github.com/robfig/cron/v3"
)
Expand Down Expand Up @@ -44,13 +46,6 @@ func getNextRuntime(canary v1.Canary, lastRuntime time.Time) (*time.Time, error)
return &t, nil
}

func def(a, b string) string {
if a != "" {
return a
}
return b
}

// unstructure marshalls a struct to and from JSON to remove any type details
func unstructure(o any) (out interface{}, err error) {
data, err := json.Marshal(o)
Expand All @@ -69,6 +64,7 @@ func template(ctx *context.Context, template v1.Template) (string, error) {
return gomplate.RunTemplate(ctx.Environment, tpl)
}

// transform generates new checks from the transformation template of the parent check
func transform(ctx *context.Context, in *pkg.CheckResult) ([]*pkg.CheckResult, error) {
var tpl v1.Template
switch v := in.Check.(type) {
Expand Down Expand Up @@ -105,22 +101,29 @@ func transform(ctx *context.Context, in *pkg.CheckResult) ([]*pkg.CheckResult, e
if t.Name != "" && t.Name != in.Check.GetName() {
// new check result created with a new name
for _, t := range transformed {
t.Icon = def(t.Icon, in.Check.GetIcon())
t.Description = def(t.Description, in.Check.GetDescription())
t.Name = def(t.Name, in.Check.GetName())
t.Type = def(t.Type, in.Check.GetType())
t.Endpoint = def(t.Endpoint, in.Check.GetEndpoint())
t.TransformDeleteStrategy = def(t.TransformDeleteStrategy, in.Check.GetTransformDeleteStrategy())
t.Icon = cUtils.Coalesce(t.Icon, in.Check.GetIcon())
t.Description = cUtils.Coalesce(t.Description, in.Check.GetDescription())
t.Name = cUtils.Coalesce(t.Name, in.Check.GetName())
t.Type = cUtils.Coalesce(t.Type, in.Check.GetType())
t.Endpoint = cUtils.Coalesce(t.Endpoint, in.Check.GetEndpoint())
t.TransformDeleteStrategy = cUtils.Coalesce(t.TransformDeleteStrategy, in.Check.GetTransformDeleteStrategy())

r := t.ToCheckResult()
r.Canary = in.Canary
r.Canary.Namespace = def(t.Namespace, r.Canary.Namespace)
r.Canary.Namespace = cUtils.Coalesce(t.Namespace, r.Canary.Namespace)
if r.Canary.Labels == nil {
r.Canary.Labels = make(map[string]string)
}

// We use this label to set the transformed column to true
// This label is used and then removed in pkg.FromV1 function
// this label are used and then removed in pkg.FromV1 function
r.Canary.Labels["transformed"] = "true" //nolint:goconst
if t.DeletedAt != nil && !t.DeletedAt.IsZero() {
r.Canary.DeletionTimestamp = &metav1.Time{
Time: *t.DeletedAt,
}
}

r.Labels = t.Labels
r.Transformed = true
results = append(results, &r)
Expand Down
2 changes: 1 addition & 1 deletion checks/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func getLabelString(labels map[string]string) string {
return s
}

func exportCheckMetrics(ctx *context.Context, results pkg.Results) {
func ExportCheckMetrics(ctx *context.Context, results pkg.Results) {
if len(results) == 0 {
return
}
Expand Down
14 changes: 7 additions & 7 deletions checks/runchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
"github.com/flanksource/canary-checker/pkg"
"github.com/flanksource/canary-checker/pkg/db"
"github.com/flanksource/commons/logger"
"github.com/patrickmn/go-cache"
gocache "github.com/patrickmn/go-cache"
)

var checksCache = cache.New(5*time.Minute, 5*time.Minute)
var checksCache = gocache.New(5*time.Minute, 5*time.Minute)

var DisabledChecks []string

Expand Down Expand Up @@ -92,16 +92,16 @@ func RunChecks(ctx *context.Context) ([]*pkg.CheckResult, error) {
}

result := c.Run(ctx)
transformedResults := transformResults(ctx, result)
transformedResults := TransformResults(ctx, result)
results = append(results, transformedResults...)

exportCheckMetrics(ctx, transformedResults)
ExportCheckMetrics(ctx, transformedResults)
}

return processResults(ctx, results), nil
return ProcessResults(ctx, results), nil
}

func transformResults(ctx *context.Context, in []*pkg.CheckResult) (out []*pkg.CheckResult) {
func TransformResults(ctx *context.Context, in []*pkg.CheckResult) (out []*pkg.CheckResult) {
for _, r := range in {
checkCtx := ctx.WithCheckResult(r)
transformed, err := transform(checkCtx, r)
Expand All @@ -117,7 +117,7 @@ func transformResults(ctx *context.Context, in []*pkg.CheckResult) (out []*pkg.C
return out
}

func processResults(ctx *context.Context, results []*pkg.CheckResult) []*pkg.CheckResult {
func ProcessResults(ctx *context.Context, results []*pkg.CheckResult) []*pkg.CheckResult {
if ctx.Canary.Spec.ResultMode == "" {
return results
}
Expand Down
3 changes: 3 additions & 0 deletions checks/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package checks

const WebhookCheckType = "webhook"
3 changes: 3 additions & 0 deletions cmd/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ func serve() {
e.POST("/api/push", api.PushHandler)
e.GET("/api/details", api.DetailsHandler)
e.GET("/api/topology", api.Topology)

e.POST("/webhook/:id", api.WebhookHandler)

e.GET("/metrics", echo.WrapHandler(promhttp.HandlerFor(prom.DefaultGatherer, promhttp.HandlerOpts{})))
e.GET("/health", func(c echo.Context) error {
return c.String(http.StatusOK, "OK")
Expand Down
109 changes: 109 additions & 0 deletions config/deploy/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5439,6 +5439,115 @@ spec:
- name
type: object
type: array
webhook:
properties:
description:
description: Description for the check
type: string
display:
properties:
expr:
type: string
javascript:
type: string
jsonPath:
type: string
template:
type: string
type: object
icon:
description: Icon for overwriting default icon on the dashboard
type: string
labels:
additionalProperties:
type: string
description: Labels for the check
type: object
metrics:
description: Metrics to expose from check results
items:
properties:
labels:
items:
properties:
name:
type: string
value:
type: string
valueExpr:
type: string
required:
- name
type: object
type: array
name:
type: string
type:
type: string
value:
type: string
type: object
type: array
name:
description: Name of the check
type: string
test:
properties:
expr:
type: string
javascript:
type: string
jsonPath:
type: string
template:
type: string
type: object
token:
description: Token is an optional authorization token to run this check
properties:
name:
type: string
value:
type: string
valueFrom:
properties:
configMapKeyRef:
properties:
key:
type: string
name:
type: string
required:
- key
type: object
secretKeyRef:
properties:
key:
type: string
name:
type: string
required:
- key
type: object
type: object
type: object
transform:
properties:
expr:
type: string
javascript:
type: string
jsonPath:
type: string
template:
type: string
type: object
transformDeleteStrategy:
description: Transformed checks have a delete strategy on deletion they can either be marked healthy, unhealthy or left as is
type: string
required:
- name
type: object
type: object
status:
description: CanaryStatus defines the observed state of Canary
Expand Down
Loading

0 comments on commit b4717c4

Please sign in to comment.