Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c27fcb895 | ||
|
|
3db5894e90 | ||
|
|
9b1d15c9e0 | ||
|
|
1855718e46 | ||
|
|
d5f2d92e8e |
2
.github/workflows/benchmark.yml
vendored
2
.github/workflows/benchmark.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
build:
|
||||
name: benchmark
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
timeout-minutes: 15
|
||||
steps:
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
|
||||
2
.github/workflows/publish-custom.yml
vendored
2
.github/workflows/publish-custom.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
jobs:
|
||||
publish-custom:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
|
||||
2
.github/workflows/publish-experimental.yml
vendored
2
.github/workflows/publish-experimental.yml
vendored
@@ -3,7 +3,7 @@ on: [workflow_dispatch]
|
||||
jobs:
|
||||
publish-experimental:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
|
||||
2
.github/workflows/publish-latest.yml
vendored
2
.github/workflows/publish-latest.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
publish-latest:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ (github.event.workflow_run.conclusion == 'success') && (github.event.workflow_run.head_repository.full_name == github.repository) }}
|
||||
timeout-minutes: 90
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
|
||||
2
.github/workflows/publish-release.yml
vendored
2
.github/workflows/publish-release.yml
vendored
@@ -6,7 +6,7 @@ jobs:
|
||||
publish-release:
|
||||
name: publish-release
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 120
|
||||
timeout-minutes: 240
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up QEMU
|
||||
|
||||
2
.github/workflows/test-ui.yml
vendored
2
.github/workflows/test-ui.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
test-ui:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: make frontend-install-dependencies
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -14,7 +14,7 @@ on:
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/setup-go@v5
|
||||
with:
|
||||
|
||||
@@ -321,13 +321,14 @@ external-endpoints:
|
||||
|
||||
To push the status of an external endpoint, the request would have to look like this:
|
||||
```
|
||||
POST /api/v1/endpoints/{key}/external?success={success}&error={error}
|
||||
POST /api/v1/endpoints/{key}/external?success={success}&error={error}&duration={duration}
|
||||
```
|
||||
Where:
|
||||
- `{key}` has the pattern `<GROUP_NAME>_<ENDPOINT_NAME>` in which both variables have ` `, `/`, `_`, `,`, `.` and `#` replaced by `-`.
|
||||
- Using the example configuration above, the key would be `core_ext-ep-test`.
|
||||
- `{success}` is a boolean (`true` or `false`) value indicating whether the health check was successful or not.
|
||||
- `{error}`: a string describing the reason for a failed health check. If {success} is false, this should contain the error message; if the check is successful, it can be omitted or left empty.
|
||||
- `{error}` (optional): a string describing the reason for a failed health check. If {success} is false, this should contain the error message; if the check is successful.
|
||||
- `{duration}` (optional): the time that the request took as a duration string (e.g. 10s).
|
||||
|
||||
You must also pass the token as a `Bearer` token in the `Authorization` header.
|
||||
|
||||
|
||||
@@ -46,6 +46,14 @@ func CreateExternalEndpointResult(cfg *config.Config) fiber.Handler {
|
||||
Success: c.QueryBool("success"),
|
||||
Errors: []string{},
|
||||
}
|
||||
if len(c.Query("duration")) > 0 {
|
||||
parsedDuration, err := time.ParseDuration(c.Query("duration"))
|
||||
if err != nil {
|
||||
logr.Errorf("[api.CreateExternalEndpointResult] Invalid duration from string=%s with error: %s", c.Query("duration"), err.Error())
|
||||
return c.Status(400).SendString("invalid duration: " + err.Error())
|
||||
}
|
||||
result.Duration = parsedDuration
|
||||
}
|
||||
if !result.Success && c.Query("error") != "" {
|
||||
result.Errors = append(result.Errors, c.Query("error"))
|
||||
}
|
||||
|
||||
@@ -70,6 +70,12 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
AuthorizationHeaderBearerToken: "Bearer token",
|
||||
ExpectedCode: 400,
|
||||
},
|
||||
{
|
||||
Name: "bad-duration-value",
|
||||
Path: "/api/v1/endpoints/g_n/external?success=true&duration=invalid",
|
||||
AuthorizationHeaderBearerToken: "Bearer token",
|
||||
ExpectedCode: 400,
|
||||
},
|
||||
{
|
||||
Name: "good-token-success-true",
|
||||
Path: "/api/v1/endpoints/g_n/external?success=true",
|
||||
@@ -82,6 +88,12 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
AuthorizationHeaderBearerToken: "Bearer token",
|
||||
ExpectedCode: 200,
|
||||
},
|
||||
{
|
||||
Name: "good-duration-success-true",
|
||||
Path: "/api/v1/endpoints/g_n/external?success=true&duration=10s",
|
||||
AuthorizationHeaderBearerToken: "Bearer token",
|
||||
ExpectedCode: 200,
|
||||
},
|
||||
{
|
||||
Name: "good-token-success-false",
|
||||
Path: "/api/v1/endpoints/g_n/external?success=false",
|
||||
@@ -118,7 +130,7 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
})
|
||||
}
|
||||
t.Run("verify-end-results", func(t *testing.T) {
|
||||
endpointStatus, err := store.Get().GetEndpointStatus("g", "n", paging.NewEndpointStatusParams().WithResults(1, 10))
|
||||
endpointStatus, err := store.Get().GetEndpointStatus("g", "n", paging.NewEndpointStatusParams().WithResults(1, 11))
|
||||
if err != nil {
|
||||
t.Errorf("failed to get endpoint status: %s", err.Error())
|
||||
return
|
||||
@@ -126,8 +138,8 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
if endpointStatus.Key != "g_n" {
|
||||
t.Errorf("expected key to be g_n but got %s", endpointStatus.Key)
|
||||
}
|
||||
if len(endpointStatus.Results) != 5 {
|
||||
t.Errorf("expected 3 results but got %d", len(endpointStatus.Results))
|
||||
if len(endpointStatus.Results) != 6 {
|
||||
t.Errorf("expected 6 results but got %d", len(endpointStatus.Results))
|
||||
}
|
||||
if !endpointStatus.Results[0].Success {
|
||||
t.Errorf("expected first result to be successful")
|
||||
@@ -138,8 +150,8 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
if len(endpointStatus.Results[1].Errors) > 0 {
|
||||
t.Errorf("expected second result to have no errors")
|
||||
}
|
||||
if endpointStatus.Results[2].Success {
|
||||
t.Errorf("expected third result to be unsuccessful")
|
||||
if endpointStatus.Results[2].Duration == 0 || endpointStatus.Results[2].Duration.Seconds() != 10 {
|
||||
t.Errorf("expected third result to have a duration of 10 seconds")
|
||||
}
|
||||
if endpointStatus.Results[3].Success {
|
||||
t.Errorf("expected fourth result to be unsuccessful")
|
||||
@@ -147,8 +159,11 @@ func TestCreateExternalEndpointResult(t *testing.T) {
|
||||
if endpointStatus.Results[4].Success {
|
||||
t.Errorf("expected fifth result to be unsuccessful")
|
||||
}
|
||||
if len(endpointStatus.Results[4].Errors) == 0 || endpointStatus.Results[4].Errors[0] != "failed" {
|
||||
t.Errorf("expected fifth result to have errors: failed")
|
||||
if endpointStatus.Results[5].Success {
|
||||
t.Errorf("expected sixth result to be unsuccessful")
|
||||
}
|
||||
if len(endpointStatus.Results[5].Errors) == 0 || endpointStatus.Results[5].Errors[0] != "failed" {
|
||||
t.Errorf("expected sixth result to have errors: failed")
|
||||
}
|
||||
externalEndpointFromConfig := cfg.GetExternalEndpointByKey("g_n")
|
||||
if externalEndpointFromConfig.NumberOfFailuresInARow != 3 {
|
||||
|
||||
12
api/util.go
12
api/util.go
@@ -34,11 +34,13 @@ func extractPageAndPageSizeFromRequest(c *fiber.Ctx, maximumNumberOfResults int)
|
||||
if err != nil {
|
||||
pageSize = DefaultPageSize
|
||||
}
|
||||
if pageSize > maximumNumberOfResults {
|
||||
pageSize = maximumNumberOfResults
|
||||
} else if pageSize < 1 {
|
||||
pageSize = DefaultPageSize
|
||||
}
|
||||
}
|
||||
if page == 1 && pageSize > maximumNumberOfResults {
|
||||
// If the page is 1 and the page size is greater than the maximum number of results, return
|
||||
// no more than the maximum number of results
|
||||
pageSize = maximumNumberOfResults
|
||||
} else if pageSize < 1 {
|
||||
pageSize = DefaultPageSize
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ type Config struct {
|
||||
func (config *Config) GetEndpointByKey(key string) *endpoint.Endpoint {
|
||||
for i := 0; i < len(config.Endpoints); i++ {
|
||||
ep := config.Endpoints[i]
|
||||
if ep.Key() == key {
|
||||
if ep.Key() == strings.ToLower(key) {
|
||||
return ep
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ func (config *Config) GetEndpointByKey(key string) *endpoint.Endpoint {
|
||||
func (config *Config) GetExternalEndpointByKey(key string) *endpoint.ExternalEndpoint {
|
||||
for i := 0; i < len(config.ExternalEndpoints); i++ {
|
||||
ee := config.ExternalEndpoints[i]
|
||||
if ee.Key() == key {
|
||||
if ee.Key() == strings.ToLower(key) {
|
||||
return ee
|
||||
}
|
||||
}
|
||||
@@ -411,8 +411,8 @@ func validateAlertingConfig(alertingConfig *alerting.Config, endpoints []*endpoi
|
||||
alert.TypeGitea,
|
||||
alert.TypeGoogleChat,
|
||||
alert.TypeGotify,
|
||||
alert.TypeHomeAssistant,
|
||||
alert.TypeIlert,
|
||||
alert.TypeHomeAssistant,
|
||||
alert.TypeIlert,
|
||||
alert.TypeIncidentIO,
|
||||
alert.TypeJetBrainsSpace,
|
||||
alert.TypeMatrix,
|
||||
|
||||
@@ -35,7 +35,10 @@ type Config struct {
|
||||
CustomCSS string `yaml:"custom-css,omitempty"` // Custom CSS to include in the page
|
||||
DarkMode *bool `yaml:"dark-mode,omitempty"` // DarkMode is a flag to enable dark mode by default
|
||||
|
||||
MaximumNumberOfResults int // MaximumNumberOfResults to display on the page, it's not configurable because we're passing it from the storage config
|
||||
//////////////////////////////////////////////
|
||||
// Non-configurable - used for UI rendering //
|
||||
//////////////////////////////////////////////
|
||||
MaximumNumberOfResults int `yaml:"-"` // MaximumNumberOfResults to display on the page, it's not configurable because we're passing it from the storage config
|
||||
}
|
||||
|
||||
func (cfg *Config) IsDarkMode() bool {
|
||||
|
||||
Reference in New Issue
Block a user