diff --git a/internal/kubenurse/server.go b/internal/kubenurse/server.go index a045fde..b9c3f59 100644 --- a/internal/kubenurse/server.go +++ b/internal/kubenurse/server.go @@ -176,6 +176,19 @@ func New(c client.Client) (*Server, error) { //nolint:funlen // TODO: use a flag chk.UseTLS = server.useTLS + // Extra checks parsing + if extraChecks := os.Getenv("KUBENURSE_EXTRA_CHECKS"); extraChecks != "" { + for _, extraCheck := range strings.Split(extraChecks, "|") { + requestType, url, fnd := strings.Cut(extraCheck, ":") + if !fnd { + slog.Error("couldn't parse one of extraChecks", "extraCheck", extraCheck) + return nil, fmt.Errorf("extra checks parsing - missing colon ':' between metric name and url") + } + + chk.ExtraChecks[requestType] = url + } + } + server.checker = chk // setup http routes diff --git a/internal/kubenurse/server_test.go b/internal/kubenurse/server_test.go index 130e97b..9034d4b 100644 --- a/internal/kubenurse/server_test.go +++ b/internal/kubenurse/server_test.go @@ -2,6 +2,7 @@ package kubenurse import ( "context" + "os" "testing" "time" @@ -12,16 +13,22 @@ import ( func TestCombined(t *testing.T) { r := require.New(t) + os.Setenv("KUBENURSE_EXTRA_CHECKS", "cloudy_endpoint:http://cloudy.enpdoint:1234/test|ep_number_two:http://interesting.endpoint:8080/abcd") fakeClient := fake.NewFakeClient() kubenurse, err := New(fakeClient) r.NoError(err) r.NotNil(kubenurse) + r.Equal(map[string]string{ + "ep_number_two": "http://interesting.endpoint:8080/abcd", + "cloudy_endpoint": "http://cloudy.enpdoint:1234/test", + }, kubenurse.checker.ExtraChecks) + t.Run("start/stop", func(t *testing.T) { r := require.New(t) errc := make(chan error, 1) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) go func() { // blocks until shutdown is called err := kubenurse.Run(ctx) diff --git a/internal/servicecheck/servicecheck.go b/internal/servicecheck/servicecheck.go index f70b344..5197176 100644 --- a/internal/servicecheck/servicecheck.go +++ b/internal/servicecheck/servicecheck.go @@ -63,6 +63,7 @@ func New(cl client.Client, promRegistry *prometheus.Registry, client: cl, httpClient: httpClient, cacheTTL: cacheTTL, + ExtraChecks: make(map[string]string), }, nil } @@ -95,6 +96,14 @@ func (c *Checker) Run(ctx context.Context) { go c.measure(ctx, &wg, &result, c.MeIngress, meIngress) go c.measure(ctx, &wg, &result, c.MeService, meService) + wg.Add(len(c.ExtraChecks)) + + for metricName, url := range c.ExtraChecks { + go c.measure(ctx, &wg, &result, + func(ctx context.Context) string { return c.doRequest(ctx, url, false) }, + metricName) + } + if c.SkipCheckNeighbourhood { result.Store(NeighbourhoodState, skippedStr) return diff --git a/internal/servicecheck/servicecheck_test.go b/internal/servicecheck/servicecheck_test.go index 8acb426..c7a6efd 100644 --- a/internal/servicecheck/servicecheck_test.go +++ b/internal/servicecheck/servicecheck_test.go @@ -37,6 +37,10 @@ func TestCombined(t *testing.T) { fakeClient := fake.NewFakeClient(&fakeNeighbourPod) checker, err := New(fakeClient, prometheus.NewRegistry(), false, 3*time.Second, prometheus.DefBuckets) + checker.ExtraChecks = map[string]string{ + "check_number_two": "http://interesting.endpoint:8080/abcd", + "cloudy_check": "http://cloudy.enpdoint:1234/test", + } r.NoError(err) r.NotNil(checker) @@ -45,5 +49,6 @@ func TestCombined(t *testing.T) { checker.Run(context.Background()) r.Equal(okStr, checker.LastCheckResult[NeighbourhoodState]) + r.Equal(errStr, checker.LastCheckResult["cloudy_check"]) // test extra endpoint functionality }) } diff --git a/internal/servicecheck/types.go b/internal/servicecheck/types.go index 5b97728..9a6f22f 100644 --- a/internal/servicecheck/types.go +++ b/internal/servicecheck/types.go @@ -41,6 +41,9 @@ type Checker struct { allowUnschedulable bool SkipCheckNeighbourhood bool + // Additional endpoints + ExtraChecks map[string]string + // TLS UseTLS bool