Skip to content

Commit

Permalink
Merge branch 'master' into gitlab-pull-push-checker
Browse files Browse the repository at this point in the history
  • Loading branch information
wwwlde committed Oct 3, 2023
2 parents 5a12453 + 8fbe884 commit c518946
Show file tree
Hide file tree
Showing 18 changed files with 295 additions and 298 deletions.
2 changes: 1 addition & 1 deletion api/context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ func New(client *kommons.Client, kubernetes kubernetes.Interface, db *gorm.DB, c
}

func (ctx *Context) IsDebug() bool {
return ctx.Canary.IsDebug()
return ctx.Canary.IsDebug() || ctx.IsTrace()
}

func (ctx *Context) IsTrace() bool {
Expand Down
4 changes: 2 additions & 2 deletions api/v1/canary_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ type CanarySpec struct {
MongoDB []MongoDBCheck `yaml:"mongodb,omitempty" json:"mongodb,omitempty"`
CloudWatch []CloudWatchCheck `yaml:"cloudwatch,omitempty" json:"cloudwatch,omitempty"`
GitHub []GitHubCheck `yaml:"github,omitempty" json:"github,omitempty"`
GitLab []GitLabCheck `yaml:"gitlab,omitempty" json:"gitlab,omitempty"`
GitProtocol []GitProtocolCheck `yaml:"gitProtocol,omitempty" json:"gitProtocol,omitempty"`
Kubernetes []KubernetesCheck `yaml:"kubernetes,omitempty" json:"kubernetes,omitempty"`
Folder []FolderCheck `yaml:"folder,omitempty" json:"folder,omitempty"`
Exec []ExecCheck `yaml:"exec,omitempty" json:"exec,omitempty"`
Expand Down Expand Up @@ -162,7 +162,7 @@ func (spec CanarySpec) GetAllChecks() []external.Check {
for _, check := range spec.GitHub {
checks = append(checks, check)
}
for _, check := range spec.GitLab {
for _, check := range spec.GitProtocol {
checks = append(checks, check)
}
for _, check := range spec.Kubernetes {
Expand Down
10 changes: 5 additions & 5 deletions api/v1/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,7 @@ func (c GitHubCheck) GetEndpoint() string {
return strings.ReplaceAll(c.Query, " ", "-")
}

type GitLabCheck struct {
type GitProtocolCheck struct {
Description `yaml:",inline" json:",inline"`
Templatable `yaml:",inline" json:",inline"`
ConnectionName string `yaml:"connection,omitempty" json:"connection,omitempty"`
Expand All @@ -788,11 +788,11 @@ type GitLabCheck struct {
Password types.EnvVar `yaml:"password,omitempty" json:"password,omitempty"`
}

func (c GitLabCheck) GetType() string {
return "gitProtocol"
func (c GitProtocolCheck) GetType() string {
return "gitprotocol"
}

func (c GitLabCheck) GetEndpoint() string {
func (c GitProtocolCheck) GetEndpoint() string {
return strings.ReplaceAll(c.Repository, "/", "-")
}

Expand Down Expand Up @@ -1370,7 +1370,7 @@ var AllChecks = []external.Check{
ExecCheck{},
FolderCheck{},
GitHubCheck{},
GitLabCheck{},
GitProtocolCheck{},
HelmCheck{},
HTTPCheck{},
ICMPCheck{},
Expand Down
14 changes: 7 additions & 7 deletions api/v1/zz_generated.deepcopy.go

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

2 changes: 1 addition & 1 deletion checks/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var All = []Checker{
&ExecChecker{},
&FolderChecker{},
&GitHubChecker{},
&GitLabChecker{},
&GitProtocolChecker{},
&HTTPChecker{},
&IcmpChecker{},
&JmeterChecker{},
Expand Down
18 changes: 9 additions & 9 deletions checks/gitlab.go → checks/git_protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ const (
TestFileName = "test.txt"
)

type GitLabChecker struct{}
type GitProtocolChecker struct{}

func (c *GitLabChecker) Type() string {
return "gitlab"
func (c *GitProtocolChecker) Type() string {
return "gitprotocol"
}

func (c *GitLabChecker) Run(ctx *context.Context) pkg.Results {
func (c *GitProtocolChecker) Run(ctx *context.Context) pkg.Results {
var results pkg.Results
for _, conf := range ctx.Canary.Spec.GitLab {
for _, conf := range ctx.Canary.Spec.GitProtocol {
results = append(results, c.Check(ctx, conf)...)
}
return results
Expand Down Expand Up @@ -94,13 +94,13 @@ func pushChanges(repoURL, username, password string) error {
return nil
}

func (c *GitLabChecker) Check(ctx *context.Context, extConfig external.Check) pkg.Results {
check := extConfig.(v1.GitLabCheck)
func (c *GitProtocolChecker) Check(ctx *context.Context, extConfig external.Check) pkg.Results {
check := extConfig.(v1.GitProtocolCheck)
result := pkg.Success(check, ctx.Canary)
var results pkg.Results
results = append(results, result)

// Fetching GitLab Token
// Fetching Token
password, err := ctx.GetEnvValueFromCache(check.Password)
if err != nil {
return results.Failf("error fetching gitlab token from env cache: %v", err)
Expand All @@ -112,7 +112,7 @@ func (c *GitLabChecker) Check(ctx *context.Context, extConfig external.Check) pk
}

details := map[string]string{
"msg": "GitLab pull/push command succeeded.",
"msg": "Git pull/push command succeeded.",
}
result.AddDetails(details)

Expand Down
169 changes: 101 additions & 68 deletions checks/metrics.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,96 @@
package checks

import (
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
"time"

"github.com/flanksource/canary-checker/api/context"
"github.com/flanksource/canary-checker/api/external"
v1 "github.com/flanksource/canary-checker/api/v1"
"github.com/flanksource/canary-checker/pkg"
"github.com/flanksource/commons/logger"
"github.com/prometheus/client_golang/prometheus"
)

var collectorMap = make(map[string]prometheus.Collector)

func addPrometheusMetric(name, metricType string, labelNames []string) prometheus.Collector {
func getOrAddPrometheusMetric(name, metricType string, labelNames []string) (prometheus.Collector, error) {
key := name + metricType + strings.Join(labelNames, ",")
if collector, exists := collectorMap[key]; exists {
return collector, nil
}
var collector prometheus.Collector
switch metricType {
case "histogram":
collector = prometheus.NewHistogramVec(
prometheus.HistogramOpts{Name: name},
labelNames,
)
prometheus.HistogramOpts{Name: name}, labelNames)
case "counter":
collector = prometheus.NewCounterVec(
prometheus.CounterOpts{Name: name},
labelNames,
)
prometheus.CounterOpts{Name: name}, labelNames)
case "gauge":
collector = prometheus.NewGaugeVec(
prometheus.GaugeOpts{Name: name},
labelNames,
)
prometheus.GaugeOpts{Name: name}, labelNames)
default:
return nil
return nil, fmt.Errorf("unknown metric type %s", metricType)
}

collectorMap[name] = collector
prometheus.MustRegister(collector)
return collector
collectorMap[key] = collector
return collector, prometheus.Register(collector)
}

func getWithEnvironment(ctx *context.Context, r *pkg.CheckResult) *context.Context {
templateInput := map[string]any{
"result": r.Data,
"canary": map[string]any{
"name": r.Canary.GetName(),
"namespace": r.Canary.GetNamespace(),
"labels": r.Canary.GetLabels(),
"id": r.Canary.GetPersistedID(),
},
"check": map[string]any{
"name": r.Check.GetName(),
"id": r.Canary.GetCheckID(r.Check.GetName()),
"description": r.Check.GetDescription(),
"labels": r.Check.GetLabels(),
"endpoint": r.Check.GetEndpoint(),
"duration": time.Millisecond * time.Duration(r.GetDuration()),
},
}
return ctx.New(templateInput)
}

func getLabels(ctx *context.Context, metric external.Metrics) (map[string]string, []string, error) {
var labels = make(map[string]string)
var names = []string{}
for _, label := range metric.Labels {
val := label.Value
if label.ValueExpr != "" {
var err error
val, err = template(ctx, v1.Template{Expression: label.ValueExpr})
if err != nil {
return nil, nil, err
}
}
labels[label.Name] = val
names = append(names, label.Name)
}
sort.Strings(names)
return labels, names, nil
}

func getLabelString(labels map[string]string) string {
s := "{"
for k, v := range labels {
if s != "{" {
s += ", "
}
s += fmt.Sprintf("%s=%s", k, v)
}
s += "}"

return s
}

func exportCheckMetrics(ctx *context.Context, results pkg.Results) {
Expand All @@ -51,77 +104,57 @@ func exportCheckMetrics(ctx *context.Context, results pkg.Results) {
continue
}

var collector prometheus.Collector
var exists bool
if collector, exists = collectorMap[spec.Name]; !exists {
collector = addPrometheusMetric(spec.Name, spec.Type, spec.Labels.Names())
if collector == nil {
logger.Errorf("Invalid type for check.metrics %s for check[%s]", spec.Type, r.Check.GetName())
continue
}
}
ctx = getWithEnvironment(ctx, r)

// Convert result Data into JSON for templating
var rData map[string]any
resultBytes, err := json.Marshal(r.Data)
if err != nil {
logger.Errorf("Error converting check result data into json: %v", err)
continue
}
if err := json.Unmarshal(resultBytes, &rData); err != nil {
logger.Errorf("Error converting check result data into json: %v", err)
var err error
var labels map[string]string
var labelNames []string
if labels, labelNames, err = getLabels(ctx, spec); err != nil {
r.ErrorMessage(err)
continue
}

tplValue := v1.Template{Expression: spec.Value}
templateInput := map[string]any{
"result": rData,
"check": map[string]any{
"name": r.Check.GetName(),
"description": r.Check.GetDescription(),
"labels": r.Check.GetLabels(),
"endpoint": r.Check.GetEndpoint(),
"duration": r.GetDuration(),
},
}

valRaw, err := template(ctx.New(templateInput), tplValue)
if err != nil {
logger.Errorf("Error templating value for check.metrics template %s for check[%s]: %v", spec.Value, r.Check.GetName(), err)
var collector prometheus.Collector
if collector, err = getOrAddPrometheusMetric(spec.Name, spec.Type, labelNames); err != nil {
r.ErrorMessage(err)
continue
}
val, err := strconv.ParseFloat(valRaw, 64)
if err != nil {
logger.Errorf("Error converting value %s to float for check.metrics template %s for check[%s]: %v", valRaw, spec.Value, r.Check.GetName(), err)

var val float64
if val, err = getMetricValue(ctx, spec); err != nil {
r.ErrorMessage(err)
continue
}

var orderedLabelVals []string
for _, label := range spec.Labels {
val := label.Value
if label.ValueExpr != "" {
var err error
val, err = template(ctx.New(templateInput), v1.Template{Expression: label.ValueExpr})
if err != nil {
logger.Errorf("Error templating label %s:%s for check.metrics for check[%s]: %v", label.Name, label.ValueExpr, r.Check.GetName(), err)
}
}
orderedLabelVals = append(orderedLabelVals, val)
if ctx.IsDebug() {
ctx.Debugf("%s%v=%0.3f", spec.Name, getLabelString(labels), val)
}

switch collector := collector.(type) {
case *prometheus.HistogramVec:
collector.WithLabelValues(orderedLabelVals...).Observe(val)
collector.With(labels).Observe(val)
case *prometheus.GaugeVec:
collector.WithLabelValues(orderedLabelVals...).Set(val)
collector.With(labels).Set(val)
case *prometheus.CounterVec:
if val <= 0 {
continue
}
collector.WithLabelValues(orderedLabelVals...).Add(val)
default:
logger.Errorf("Got unknown type for check.metrics %T", collector)
collector.With(labels).Add(val)
}
}
}
}

func getMetricValue(ctx *context.Context, spec external.Metrics) (float64, error) {
tplValue := v1.Template{Expression: spec.Value}

valRaw, err := template(ctx, tplValue)
if err != nil {
return 0, err
}
val, err := strconv.ParseFloat(valRaw, 64)
if err != nil {
return 0, fmt.Errorf("%s is not a number", valRaw)
}
return val, nil
}
2 changes: 1 addition & 1 deletion config/deploy/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2908,7 +2908,7 @@ spec:
- query
type: object
type: array
gitlab:
gitProtocol:
items:
properties:
connection:
Expand Down
2 changes: 1 addition & 1 deletion config/deploy/manifests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2908,7 +2908,7 @@ spec:
- query
type: object
type: array
gitlab:
gitProtocol:
items:
properties:
connection:
Expand Down
Loading

0 comments on commit c518946

Please sign in to comment.