Skip to content

Commit

Permalink
Added webserver for query applied rules (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfradehubs authored Dec 10, 2024
1 parent aa08d7b commit 7916426
Show file tree
Hide file tree
Showing 14 changed files with 507 additions and 32 deletions.
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o ma
# Use distroless as minimal base image to package the manager binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
FROM gcr.io/distroless/static:nonroot
ENV APP_ENV=production
WORKDIR /
COPY --from=builder /workspace/manager .
COPY --from=builder /workspace/internal/webserver/static /static
USER 65532:65532

ENTRYPOINT ["/manager"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ They are described in the following table:
| `--leader-elect` | Enable leader election for controller manager | `false` |
| `--metrics-secure` | If set the metrics endpoint is served securely | `false` |
| `--enable-http2` | If set, HTTP/2 will be enabled for the metrirs | `false` |
| `--webserver-address` | Webserver listen address. </br> 0 disables the webserver | `0` |


## Examples
Expand Down
12 changes: 12 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package main

import (
"context"
"crypto/tls"
"flag"
"os"
Expand All @@ -39,6 +40,7 @@ import (
"prosimcorp.com/SearchRuler/internal/controller"
"prosimcorp.com/SearchRuler/internal/globals"
"prosimcorp.com/SearchRuler/internal/pools"
"prosimcorp.com/SearchRuler/internal/webserver"
// +kubebuilder:scaffold:imports
)

Expand Down Expand Up @@ -71,6 +73,7 @@ func main() {
var probeAddr string
var secureMetrics bool
var enableHTTP2 bool
var webserverAddr string
var tlsOpts []func(*tls.Config)
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
Expand All @@ -82,6 +85,8 @@ func main() {
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
flag.BoolVar(&enableHTTP2, "enable-http2", false,
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
flag.StringVar(&webserverAddr, "webserver-address", "0",
"The address the webserver will bind to. Use :8443 for HTTPS or :8080 for HTTP or leave as 0 to disable the webserver.")
opts := zap.Options{
Development: true,
}
Expand Down Expand Up @@ -157,6 +162,13 @@ func main() {
os.Exit(1)
}

if webserverAddr != "0" {
// Create webserver for the application
go func() {
webserver.RunWebserver(context.TODO(), webserverAddr, RulesPool)
}()
}

// Create and store raw Kubernetes clients from client-go
// They are used by kubebuilder non-related processess and controllers
globals.Application.KubeRawClient, globals.Application.KubeRawCoreClient, err = globals.NewKubernetesClient()
Expand Down
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ go 1.22.0
require (
github.com/BurntSushi/toml v1.4.0
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/gofiber/fiber/v2 v2.52.5
github.com/gofiber/template/html/v2 v2.1.2
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/tidwall/gjson v1.18.0
Expand All @@ -19,6 +21,7 @@ require (
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
github.com/beorn7/perks v1.0.1 // indirect
Expand All @@ -38,6 +41,8 @@ require (
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.4 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/gofiber/template v1.8.3 // indirect
github.com/gofiber/utils v1.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
Expand All @@ -53,7 +58,11 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
Expand All @@ -64,11 +73,15 @@ require (
github.com/prometheus/client_model v0.6.1 // indirect
github.com/prometheus/common v0.55.0 // indirect
github.com/prometheus/procfs v0.15.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/cobra v1.8.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
Expand Down
29 changes: 29 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
Expand Down Expand Up @@ -52,6 +54,14 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
github.com/gofiber/template/html/v2 v2.1.2 h1:wkK/mYJ3nIhongTkG3t0QgV4ADdgOYJYVSAF2AHnh8Y=
github.com/gofiber/template/html/v2 v2.1.2/go.mod h1:E98Z/FzvpaSib06aWEgYk6GXNf3ctoyaJH8yW5ay5ak=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
Expand Down Expand Up @@ -86,6 +96,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
Expand All @@ -95,6 +107,13 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
Expand Down Expand Up @@ -123,6 +142,8 @@ github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand All @@ -149,6 +170,12 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down Expand Up @@ -200,6 +227,8 @@ golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/queryconnector_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (r *QueryConnectorReconciler) Sync(ctx context.Context, eventType watch.Eve
// If the eventType is Deleted, remove the credentials from the pool
// In other cases get the credentials from the secret and add them to the pool
if eventType == watch.Deleted {
credentialsKey := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
credentialsKey := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
r.CredentialsPool.Delete(credentialsKey)
return nil
}
Expand Down Expand Up @@ -66,7 +66,7 @@ func (r *QueryConnectorReconciler) Sync(ctx context.Context, eventType watch.Eve
}

// Save credentials in the credentials pool
key := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
key := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
r.CredentialsPool.Set(key, &pools.Credentials{
Username: username,
Password: password,
Expand Down
11 changes: 0 additions & 11 deletions internal/controller/searchrule_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,6 @@ func (r *SearchRuleReconciler) UpdateConditionAlertFiring(searchRule *v1alpha1.S
globals.UpdateCondition(&searchRule.Status.Conditions, condition)
}

// UpdateConditionNoCredsFound updates the status of the SearchRule resource with alert resolved condition
func (r *SearchRuleReconciler) UpdateConditionAlertResolved(searchRule *v1alpha1.SearchRule) {

// Create the new condition with the alert resolved status
condition := globals.NewCondition(globals.ConditionTypeState, metav1.ConditionTrue,
globals.ConditionReasonAlertResolved, globals.ConditionReasonAlertResolvedMessage)

// Update the status of the SearchRule resource
globals.UpdateCondition(&searchRule.Status.Conditions, condition)
}

// UpdateStateAlertPendingFiring updates the status of the SearchRule resource with alert pending firing condition
func (r *SearchRuleReconciler) UpdateStateAlertPendingFiring(searchRule *v1alpha1.SearchRule) {

Expand Down
52 changes: 33 additions & 19 deletions internal/controller/searchrule_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ import (
const (

// Rule states
ruleHealthyState = "Healthy"
ruleNormalState = "Normal"
ruleFiringState = "Firing"
rulePendingFiringState = "PendingFiring"
rulePendingResolvedState = "PendingResolved"
rulePendingResolvedState = "PendingResolving"

// Conditions
conditionGreaterThan = "greaterThan"
Expand Down Expand Up @@ -81,7 +81,7 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy
// If the eventType is Deleted, remove the rule from the rules pool and from the alerts pool
// In other cases, execute Sync logic
if eventType == watch.Deleted {
key := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
key := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
r.RulesPool.Delete(key)
r.AlertsPool.Delete(key)
return nil
Expand All @@ -105,14 +105,21 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy

// Get credentials for QueryConnector attached if defined
if !reflect.ValueOf(QueryConnectorResource.Spec.Credentials).IsZero() {
key := fmt.Sprintf("%s/%s", resource.Namespace, QueryConnectorResource.Name)
key := fmt.Sprintf("%s_%s", resource.Namespace, QueryConnectorResource.Name)
queryConnectorCreds, credsExists = r.QueryConnectorCredentialsPool.Get(key)
if !credsExists {
r.UpdateConditionNoCredsFound(resource)
return fmt.Errorf(MissingCredentialsMessage, key)
}
}

// Get `for` duration for the rules firing. When rule is firing during this for time,
// then the rule is really ocurring and must be an alert
forDuration, err := time.ParseDuration(resource.Spec.Condition.For)
if err != nil {
return fmt.Errorf(ForValueParseErrorMessage, err)
}

// Check if query is defined in the resource
if resource.Spec.Elasticsearch.Query == nil && resource.Spec.Elasticsearch.QueryJSON == "" {
r.UpdateConditionNoQueryFound(resource)
Expand Down Expand Up @@ -223,32 +230,37 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy
)
}

// Get ruleKey for the pool <namespace>/<name> and get rule from the pool if exists
// Get ruleKey for the pool <namespace>_<name> and get rule from the pool if exists
// If not, create a default skeleton rule and save it to the pool
ruleKey := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
ruleKey := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
rule, ruleInPool := r.RulesPool.Get(ruleKey)
if !ruleInPool {
// Initialize rule with default values
rule = &pools.Rule{
SearchRule: *resource,
FiringTime: time.Time{},
State: ruleHealthyState,
State: ruleNormalState,
ResolvingTime: time.Time{},
Value: conditionValue.Float(),
}
r.RulesPool.Set(ruleKey, rule)
}

// Get `for` duration for the rules firing. When rule is firing during this for time,
// then the rule is really ocurring and must be an alert
forDuration, err := time.ParseDuration(resource.Spec.Condition.For)
if err != nil {
return fmt.Errorf(ForValueParseErrorMessage, err)
// Check if resource is sync with the pool
if !reflect.DeepEqual(rule.SearchRule, *resource) {
rule.SearchRule = *resource
r.RulesPool.Set(ruleKey, rule)
}

// Set the current value of the condition to the rule
rule.Value = conditionValue.Float()
r.RulesPool.Set(ruleKey, rule)

// If rule is firing right now
if firing {

// If rule is not set as firing in the pool, set start fireTime and state PendingFiring
if rule.State == ruleHealthyState || rule.State == rulePendingResolvedState {
if rule.State == ruleNormalState || rule.State == rulePendingResolvedState {
rule.FiringTime = time.Now()
rule.State = rulePendingFiringState
r.RulesPool.Set(ruleKey, rule)
Expand All @@ -260,7 +272,7 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy
r.RulesPool.Set(ruleKey, rule)

// Add alert to the pool with the value, the object and the rulerAction name which will trigger the alert
alertKey := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
alertKey := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
r.AlertsPool.Set(alertKey, &pools.Alert{
RulerActionName: resource.Spec.ActionRef.Name,
SearchRule: *resource,
Expand Down Expand Up @@ -297,7 +309,7 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy
}

// If alert is not firing right now and it is not in healthy state
if !firing && rule.State != ruleHealthyState {
if !firing && rule.State != ruleNormalState {

// If rule is not marked as resolving in the pool, change state to PendingResolved and set resolvingTime now
if rule.State != rulePendingResolvedState {
Expand All @@ -310,21 +322,23 @@ func (r *SearchRuleReconciler) Sync(ctx context.Context, eventType watch.EventTy
if time.Since(rule.ResolvingTime) > forDuration {

// Remove alert from the pool
alertKey := fmt.Sprintf("%s/%s", resource.Namespace, resource.Name)
alertKey := fmt.Sprintf("%s_%s", resource.Namespace, resource.Name)
r.AlertsPool.Delete(alertKey)

// Restore rule to default values
rule = &pools.Rule{
FiringTime: time.Time{},
State: ruleHealthyState,
State: ruleNormalState,
ResolvingTime: time.Time{},
SearchRule: *resource,
Value: conditionValue.Float(),
}
r.RulesPool.Set(ruleKey, rule)

// Log and update the AlertStatus to Resolved
r.UpdateConditionAlertResolved(resource)
r.UpdateStateNormal(resource)
logger.Info(fmt.Sprintf(
"Rule %s is in resolved state. Current value is %v",
"Rule %s is in normal state. Current value is %v",
resource.Name,
conditionValue,
))
Expand Down
4 changes: 4 additions & 0 deletions internal/pools/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@ package pools
import (
"sync"
"time"

"prosimcorp.com/SearchRuler/api/v1alpha1"
)

// Rule
type Rule struct {
SearchRule v1alpha1.SearchRule
FiringTime time.Time
ResolvingTime time.Time
State string
Value float64
}

// RulesStore
Expand Down
Binary file added internal/webserver/static/public/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7916426

Please sign in to comment.