Compare commits

..

7 Commits

Author SHA1 Message Date
TwiN
6ab8899dc6 fix(condition): Partially support numbers with floating point (#434)
* docs: Don't include Pushover in alerting provider examples

* fix(condition): Partially support numbers with floating point

Fixes #433

Does not add support for decimal numbers, but it converts float64 to int64.
The reason why I'm not just using float64 instead of int64 is because float64 does not support all the numbers that int64 supports, which means this would be a breaking change. Instead, this change at least supports the non-decimal part of floating point numbers.

This is an improvement over the current implementation, as right now, numbers with decimals are just converted to 0 when compared using a non-equal operator
2023-02-15 19:30:29 -05:00
Andrii Vakarev
819abf4263 Helm chart moved from avakarev/gatus-chart to minicloudlabs/helm-charts (#428) 2023-02-13 20:04:46 -05:00
Marc Brugger
6950a080df docs(alerting): Correct newline in docu (#420) 2023-02-13 19:55:19 -05:00
TwiN
7d6923730e fix(config): Support $$ in config for literal $ (#427) 2023-02-11 22:43:13 -05:00
TwiN
542da61215 fix(ci): Use single quotes instead of double quotes 2023-02-09 21:25:06 -05:00
TwiN
45fe7beb6d fix(ci): Add missing asterisk to path-ignore elements with nested structure 2023-02-09 21:23:29 -05:00
TwiN
26611b7793 ci: Run benchmark on every new latest image 2023-02-09 21:15:36 -05:00
8 changed files with 81 additions and 13 deletions

View File

@@ -1,5 +1,9 @@
name: benchmark
on:
workflow_run:
workflows: [publish-latest]
branches: [master]
types: [completed]
workflow_dispatch:
inputs:
repository:
@@ -19,8 +23,8 @@ jobs:
- uses: actions/setup-go@v3
with:
go-version: 1.19
repository: "${{ github.event.inputs.repository }}"
ref: "${{ github.event.inputs.ref }}"
repository: "${{ github.event.inputs.repository || 'TwiN/gatus' }}"
ref: "${{ github.event.inputs.ref || 'master' }}"
- uses: actions/checkout@v3
- name: Benchmark
run: go test -bench=. ./storage/store

View File

@@ -3,14 +3,14 @@ on:
pull_request:
paths-ignore:
- '*.md'
- '.examples/*'
- '.examples/**'
push:
branches:
- master
paths-ignore:
- '*.md'
- '.github/*'
- '.examples/*'
- '.github/**'
- '.examples/**'
jobs:
test:
runs-on: ubuntu-latest

View File

@@ -10,7 +10,7 @@
Gatus is a developer-oriented health dashboard that gives you the ability to monitor your services using HTTP, ICMP, TCP, and even DNS
queries as well as evaluate the result of said queries by using a list of conditions on values like the status code,
the response time, the certificate expiration, the body and many others. The icing on top is that each of these health
checks can be paired with alerting via Slack, PagerDuty, Pushover, Discord, Twilio and more.
checks can be paired with alerting via Slack, Teams, PagerDuty, Discord, Twilio and many more.
I personally deploy it in my Kubernetes cluster and let it monitor the status of my
core applications: https://status.twin.sh/
@@ -801,7 +801,7 @@ endpoints:
| `alerting.pushover.user-key` | User or group key | `""` |
| `alerting.pushover.title` | Fixed title for all messages sent via Pushover | Name of your App in Pushover |
| `alerting.pushover.priority` | Priority of all messages, ranging from -2 (very low) to 2 (emergency) | `0` |
| `alerting.pushover.sound` | Sound of all messages<br/ >See [sounds](https://pushover.net/api#sounds) for all valid choices. | `""` |
| `alerting.pushover.sound` | Sound of all messages<br />See [sounds](https://pushover.net/api#sounds) for all valid choices. | `""` |
| `alerting.pushover.default-alert` | Default alert configuration. <br />See [Setting a default alert](#setting-a-default-alert) | N/A |
```yaml
@@ -1301,11 +1301,11 @@ Please refer to Helm's [documentation](https://helm.sh/docs/) to get started.
Once Helm is set up properly, add the repository as follows:
```console
helm repo add gatus https://avakarev.github.io/gatus-chart
helm repo add minicloudlabs https://minicloudlabs.github.io/helm-charts
```
To get more details, please check chart's [configuration](https://github.com/avakarev/gatus-chart#configuration)
and [helmfile example](https://github.com/avakarev/gatus-chart#helmfileyaml-example)
To get more details, please check [chart's configuration](https://github.com/minicloudlabs/helm-charts/tree/main/charts/gatus#configuration)
and [helmfile example](https://github.com/minicloudlabs/helm-charts/tree/main/charts/gatus#helmfileyaml-example)
### Terraform

View File

@@ -7,6 +7,7 @@ import (
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/TwiN/deepmerge"
@@ -214,8 +215,13 @@ func walkConfigDir(path string, fn fs.WalkDirFunc) error {
// parseAndValidateConfigBytes parses a Gatus configuration file into a Config struct and validates its parameters
func parseAndValidateConfigBytes(yamlBytes []byte) (config *Config, err error) {
// Replace $$ with __GATUS_LITERAL_DOLLAR_SIGN__ to prevent os.ExpandEnv from treating "$$" as if it was an
// environment variable. This allows Gatus to support literal "$" in the configuration file.
yamlBytes = []byte(strings.ReplaceAll(string(yamlBytes), "$$", "__GATUS_LITERAL_DOLLAR_SIGN__"))
// Expand environment variables
yamlBytes = []byte(os.ExpandEnv(string(yamlBytes)))
// Replace __GATUS_LITERAL_DOLLAR_SIGN__ with "$" to restore the literal "$" in the configuration file
yamlBytes = []byte(strings.ReplaceAll(string(yamlBytes), "__GATUS_LITERAL_DOLLAR_SIGN__", "$"))
// Parse configuration file
if err = yaml.Unmarshal(yamlBytes, &config); err != nil {
return

View File

@@ -1534,7 +1534,34 @@ endpoints:
}
}
func TestParseAndValidateConfigBytesWithNoEndpointsOrAutoDiscovery(t *testing.T) {
func TestParseAndValidateConfigBytesWithLiteralDollarSign(t *testing.T) {
os.Setenv("GATUS_TestParseAndValidateConfigBytesWithLiteralDollarSign", "whatever")
config, err := parseAndValidateConfigBytes([]byte(`
endpoints:
- name: website
url: https://twin.sh/health
conditions:
- "[BODY] == $$GATUS_TestParseAndValidateConfigBytesWithLiteralDollarSign"
- "[BODY] == $GATUS_TestParseAndValidateConfigBytesWithLiteralDollarSign"
`))
if err != nil {
t.Error("expected no error, got", err.Error())
}
if config == nil {
t.Fatal("Config shouldn't have been nil")
}
if config.Endpoints[0].URL != "https://twin.sh/health" {
t.Errorf("URL should have been %s", "https://twin.sh/health")
}
if config.Endpoints[0].Conditions[0] != "[BODY] == $GATUS_TestParseAndValidateConfigBytesWithLiteralDollarSign" {
t.Errorf("Condition should have been %s", "[BODY] == $GATUS_TestParseAndValidateConfigBytesWithLiteralDollarSign")
}
if config.Endpoints[0].Conditions[1] != "[BODY] == whatever" {
t.Errorf("Condition should have been %s", "[BODY] == whatever")
}
}
func TestParseAndValidateConfigBytesWithNoEndpoints(t *testing.T) {
_, err := parseAndValidateConfigBytes([]byte(``))
if err != ErrNoEndpointInConfig {
t.Error("The error returned should have been of type ErrNoEndpointInConfig")

View File

@@ -302,10 +302,18 @@ func sanitizeAndResolveNumerical(list []string, result *Result) (parameters []st
parameters, resolvedParameters := sanitizeAndResolve(list, result)
for _, element := range resolvedParameters {
if duration, err := time.ParseDuration(element); duration != 0 && err == nil {
// If the string is a duration, convert it to milliseconds
resolvedNumericalParameters = append(resolvedNumericalParameters, duration.Milliseconds())
} else if number, err := strconv.ParseInt(element, 10, 64); err != nil {
// Default to 0 if the string couldn't be converted to an integer
resolvedNumericalParameters = append(resolvedNumericalParameters, 0)
// It's not an int, so we'll check if it's a float
if f, err := strconv.ParseFloat(element, 64); err == nil {
// It's a float, but we'll convert it to an int. We're losing precision here, but it's better than
// just returning 0.
resolvedNumericalParameters = append(resolvedNumericalParameters, int64(f))
} else {
// Default to 0 if the string couldn't be converted to an integer or a float
resolvedNumericalParameters = append(resolvedNumericalParameters, 0)
}
} else {
resolvedNumericalParameters = append(resolvedNumericalParameters, number)
}

View File

@@ -294,6 +294,13 @@ func TestCondition_evaluate(t *testing.T) {
ExpectedSuccess: false,
ExpectedOutput: "[BODY].data.id (1) > 5",
},
{
Name: "body-jsonpath-float-using-greater-than-issue433", // As of v5.3.1, Gatus will convert a float to an int. We're losing precision, but it's better than just returning 0
Condition: Condition("[BODY].balance > 100"),
Result: &Result{body: []byte(`{"balance": "123.40000000000005"}`)},
ExpectedSuccess: true,
ExpectedOutput: "[BODY].balance > 100",
},
{
Name: "body-jsonpath-complex-int-using-less-than",
Condition: Condition("[BODY].data.id < 5"),

View File

@@ -158,6 +158,22 @@ func TestEval(t *testing.T) {
ExpectedOutputLength: 0,
ExpectedError: true,
},
{
Name: "float-as-string",
Path: "balance",
Data: `{"balance": "123.40000000000005"}`,
ExpectedOutput: "123.40000000000005",
ExpectedOutputLength: 18,
ExpectedError: false,
},
{
Name: "float-as-number",
Path: "balance",
Data: `{"balance": 123.40000000000005}`,
ExpectedOutput: "123.40000000000005",
ExpectedOutputLength: 18,
ExpectedError: false,
},
}
for _, scenario := range scenarios {
t.Run(scenario.Name, func(t *testing.T) {