Advisor: Allow to skip a step (#104454)

pull/105429/head^2
Andres Martinez Gotor 4 days ago committed by GitHub
parent 6f1382a0c8
commit b2387c1a31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 8
      apps/advisor/pkg/app/app.go
  2. 29
      apps/advisor/pkg/app/checks/utils.go
  3. 10
      apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go
  4. 42
      apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go
  5. 76
      apps/advisor/pkg/app/utils.go
  6. 80
      apps/advisor/pkg/app/utils_test.go
  7. 31
      public/app/api/clients/advisor/endpoints.gen.ts
  8. 13
      public/app/api/clients/advisor/index.ts
  9. 10
      scripts/generate-rtk-apis.ts

@ -33,6 +33,10 @@ func New(cfg app.Config) (app.App, error) {
if err != nil {
return nil, err
}
typesClient, err := clientGenerator.ClientFor(advisorv0alpha1.CheckTypeKind())
if err != nil {
return nil, err
}
// Initialize checks
checkMap := map[string]checks.Check{}
@ -68,7 +72,7 @@ func New(cfg app.Config) (app.App, error) {
return
}
ctx = identity.WithRequester(context.Background(), requester)
err = processCheck(ctx, logger, client, req.Object, check)
err = processCheck(ctx, logger, client, typesClient, req.Object, check)
if err != nil {
logger.Error("Error processing check", "error", err)
}
@ -84,7 +88,7 @@ func New(cfg app.Config) (app.App, error) {
return
}
ctx = identity.WithRequester(context.Background(), requester)
err = processCheckRetry(ctx, logger, client, req.Object, check)
err = processCheckRetry(ctx, logger, client, typesClient, req.Object, check)
if err != nil {
logger.Error("Error processing check retry", "error", err)
}

@ -3,6 +3,7 @@ package checks
import (
"context"
"fmt"
"maps"
"strconv"
"github.com/grafana/authlib/types"
@ -15,6 +16,8 @@ const (
TypeLabel = "advisor.grafana.app/type"
StatusAnnotation = "advisor.grafana.app/status"
RetryAnnotation = "advisor.grafana.app/retry"
IgnoreStepsAnnotation = "advisor.grafana.app/ignore-steps"
IgnoreStepsAnnotationList = "advisor.grafana.app/ignore-steps-list"
StatusAnnotationError = "error"
StatusAnnotationProcessed = "processed"
)
@ -54,12 +57,28 @@ func GetRetryAnnotation(obj resource.Object) string {
return obj.GetAnnotations()[RetryAnnotation]
}
func SetStatusAnnotation(ctx context.Context, client resource.Client, obj resource.Object, status string) error {
annotations := obj.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
func AddAnnotations(ctx context.Context, obj resource.Object, annotations map[string]string) map[string]string {
existingAnnotations := obj.GetAnnotations()
if existingAnnotations == nil {
existingAnnotations = map[string]string{}
}
maps.Copy(existingAnnotations, annotations)
return existingAnnotations
}
func DeleteAnnotations(ctx context.Context, obj resource.Object, annotations []string) map[string]string {
existingAnnotations := obj.GetAnnotations()
if existingAnnotations == nil {
existingAnnotations = map[string]string{}
}
annotations[StatusAnnotation] = status
for _, annotation := range annotations {
delete(existingAnnotations, annotation)
}
return existingAnnotations
}
func SetStatusAnnotation(ctx context.Context, client resource.Client, obj resource.Object, status string) error {
annotations := AddAnnotations(ctx, obj, map[string]string{StatusAnnotation: status})
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
Operations: []resource.PatchOperation{{
Operation: resource.PatchOpAdd,

@ -65,6 +65,13 @@ func (r *Runner) createOrUpdate(ctx context.Context, log logging.Logger, obj res
if errors.IsAlreadyExists(err) {
// Already exists, update
log.Debug("Check type already exists, updating", "identifier", id)
// Retrieve current annotations to avoid overriding them
current, err := r.client.Get(ctx, obj.GetStaticMetadata().Identifier())
if err != nil {
return err
}
annotations := current.GetAnnotations()
obj.SetAnnotations(annotations)
_, err = r.client.Update(ctx, id, obj, resource.UpdateOptions{})
if err != nil {
// Ignore the error, it's probably due to a race condition
@ -97,7 +104,8 @@ func (r *Runner) Run(ctx context.Context) error {
Namespace: r.namespace,
Annotations: map[string]string{
// Flag to indicate feature availability
checks.RetryAnnotation: "1",
checks.RetryAnnotation: "1",
checks.IgnoreStepsAnnotation: "1",
},
},
Spec: advisorv0alpha1.CheckTypeSpec{

@ -11,6 +11,7 @@ import (
advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1"
"github.com/grafana/grafana/apps/advisor/pkg/app/checks"
k8sErrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
@ -18,6 +19,7 @@ func TestCheckTypesRegisterer_Run(t *testing.T) {
tests := []struct {
name string
checks []checks.Check
getFunc func(ctx context.Context, id resource.Identifier) (resource.Object, error)
createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error)
updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error)
expectedErr error
@ -56,6 +58,37 @@ func TestCheckTypesRegisterer_Run(t *testing.T) {
},
expectedErr: nil,
},
{
name: "create already exists, with custom annotations",
checks: []checks.Check{
&mockCheck{
id: "check1",
steps: []checks.Step{
&mockStep{id: "step1", title: "Step 1", description: "Description 1"},
},
},
},
getFunc: func(ctx context.Context, id resource.Identifier) (resource.Object, error) {
return &advisorv0alpha1.CheckType{
ObjectMeta: metav1.ObjectMeta{
Name: "check1",
Annotations: map[string]string{
checks.IgnoreStepsAnnotationList: "step1",
},
},
}, nil
},
createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
return nil, k8sErrs.NewAlreadyExists(schema.GroupResource{}, obj.GetName())
},
updateFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) {
if obj.GetAnnotations()[checks.IgnoreStepsAnnotationList] != "step1" {
return nil, fmt.Errorf("expected annotation %s, got %s", "step1", obj.GetAnnotations()[checks.IgnoreStepsAnnotationList])
}
return obj, nil
},
expectedErr: nil,
},
{
name: "create error",
checks: []checks.Check{
@ -115,6 +148,7 @@ func TestCheckTypesRegisterer_Run(t *testing.T) {
r := &Runner{
checkRegistry: &mockCheckRegistry{checks: tt.checks},
client: &mockClient{
getFunc: tt.getFunc,
createFunc: tt.createFunc,
updateFunc: tt.updateFunc,
},
@ -187,10 +221,18 @@ func (m *mockStep) Run(ctx context.Context, log logging.Logger, obj *advisorv0al
type mockClient struct {
resource.Client
getFunc func(ctx context.Context, id resource.Identifier) (resource.Object, error)
createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error)
updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error)
}
func (m *mockClient) Get(ctx context.Context, id resource.Identifier) (resource.Object, error) {
if m.getFunc != nil {
return m.getFunc(ctx, id)
}
return advisorv0alpha1.CheckTypeKind().ZeroValue(), nil
}
func (m *mockClient) Create(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) {
return m.createFunc(ctx, id, obj, opts)
}

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"slices"
"strings"
"sync"
"github.com/grafana/grafana-app-sdk/logging"
@ -31,7 +32,7 @@ func getCheck(obj resource.Object, checkMap map[string]checks.Check) (checks.Che
return c, nil
}
func processCheck(ctx context.Context, log logging.Logger, client resource.Client, obj resource.Object, check checks.Check) error {
func processCheck(ctx context.Context, log logging.Logger, client resource.Client, typesClient resource.Client, obj resource.Object, check checks.Check) error {
status := checks.GetStatusAnnotation(obj)
if status != "" {
// Check already processed
@ -54,8 +55,20 @@ func processCheck(ctx context.Context, log logging.Logger, client resource.Clien
}
return fmt.Errorf("error initializing check: %w", err)
}
// Get the check type
var checkType resource.Object
checkType, err = typesClient.Get(ctx, resource.Identifier{
Namespace: obj.GetNamespace(),
Name: check.ID(),
})
if err != nil {
return err
}
// Run the steps
steps := check.Steps()
steps, err := filterSteps(checkType, check.Steps())
if err != nil {
return err
}
failures, err := runStepsInParallel(ctx, log, &c.Spec, steps, items)
if err != nil {
setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
@ -69,20 +82,27 @@ func processCheck(ctx context.Context, log logging.Logger, client resource.Clien
Failures: failures,
Count: int64(len(items)),
}
err = checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationProcessed)
if err != nil {
return err
}
// Set the status annotation to processed and annotate the steps ignored
annotations := checks.AddAnnotations(ctx, obj, map[string]string{
checks.StatusAnnotation: checks.StatusAnnotationProcessed,
checks.IgnoreStepsAnnotationList: checkType.GetAnnotations()[checks.IgnoreStepsAnnotationList],
})
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
Operations: []resource.PatchOperation{{
Operation: resource.PatchOpAdd,
Path: "/status/report",
Value: *report,
}},
Operations: []resource.PatchOperation{
{
Operation: resource.PatchOpAdd,
Path: "/status/report",
Value: *report,
}, {
Operation: resource.PatchOpAdd,
Path: "/metadata/annotations",
Value: annotations,
},
},
}, resource.PatchOptions{}, obj)
}
func processCheckRetry(ctx context.Context, log logging.Logger, client resource.Client, obj resource.Object, check checks.Check) error {
func processCheckRetry(ctx context.Context, log logging.Logger, client resource.Client, typesClient resource.Client, obj resource.Object, check checks.Check) error {
status := checks.GetStatusAnnotation(obj)
if status == "" || status == checks.StatusAnnotationError {
// Check not processed yet or errored
@ -111,8 +131,20 @@ func processCheckRetry(ctx context.Context, log logging.Logger, client resource.
}
return fmt.Errorf("error initializing check: %w", err)
}
// Get the check type
var checkType resource.Object
checkType, err = typesClient.Get(ctx, resource.Identifier{
Namespace: obj.GetNamespace(),
Name: check.ID(),
})
if err != nil {
return err
}
// Run the steps
steps := check.Steps()
steps, err := filterSteps(checkType, check.Steps())
if err != nil {
return err
}
failures, err := runStepsInParallel(ctx, log, &c.Spec, steps, []any{item})
if err != nil {
setErr := checks.SetStatusAnnotation(ctx, client, obj, checks.StatusAnnotationError)
@ -137,8 +169,7 @@ func processCheckRetry(ctx context.Context, log logging.Logger, client resource.
return false
})
// Delete the retry annotation to mark the check as processed
annotations := obj.GetAnnotations()
delete(annotations, checks.RetryAnnotation)
annotations := checks.DeleteAnnotations(ctx, obj, []string{checks.RetryAnnotation})
return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{
Operations: []resource.PatchOperation{{
Operation: resource.PatchOpAdd,
@ -193,3 +224,18 @@ func runStepsInParallel(ctx context.Context, log logging.Logger, spec *advisorv0
wg.Wait()
return reportFailures, internalErr
}
func filterSteps(checkType resource.Object, steps []checks.Step) ([]checks.Step, error) {
ignoreStepsList := checkType.GetAnnotations()[checks.IgnoreStepsAnnotationList]
if ignoreStepsList != "" {
filteredSteps := []checks.Step{}
ignoreStepsList := strings.Split(ignoreStepsList, ",")
for _, step := range steps {
if !slices.Contains(ignoreStepsList, step.ID()) {
filteredSteps = append(filteredSteps, step)
}
}
return filteredSteps, nil
}
return steps, nil
}

@ -58,14 +58,15 @@ func TestProcessCheck(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{
items: []any{"item"},
}
err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
err = processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationProcessed, obj.GetAnnotations()[checks.StatusAnnotation])
}
func TestProcessMultipleCheckItems(t *testing.T) {
@ -77,6 +78,7 @@ func TestProcessMultipleCheckItems(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
items := make([]any, 100)
for i := range items {
@ -90,9 +92,9 @@ func TestProcessMultipleCheckItems(t *testing.T) {
items: items,
}
err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
err = processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationProcessed, obj.GetAnnotations()[checks.StatusAnnotation])
r := client.lastValue.(advisorv0alpha1.CheckV0alpha1StatusReport)
assert.Equal(t, r.Count, int64(100))
assert.Len(t, r.Failures, 50)
@ -100,12 +102,13 @@ func TestProcessMultipleCheckItems(t *testing.T) {
func TestProcessCheck_AlreadyProcessed(t *testing.T) {
obj := &advisorv0alpha1.Check{}
obj.SetAnnotations(map[string]string{checks.StatusAnnotation: "processed"})
obj.SetAnnotations(map[string]string{checks.StatusAnnotation: checks.StatusAnnotationProcessed})
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{}
err := processCheck(ctx, logging.DefaultLogger, client, obj, check)
err := processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
}
@ -118,6 +121,7 @@ func TestProcessCheck_RunError(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{
@ -125,9 +129,35 @@ func TestProcessCheck_RunError(t *testing.T) {
err: errors.New("run error"),
}
err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
err = processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.Error(t, err)
assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationError, obj.GetAnnotations()[checks.StatusAnnotation])
}
func TestProcessCheck_IgnoreSteps(t *testing.T) {
checkType := &advisorv0alpha1.CheckType{}
checkType.SetAnnotations(map[string]string{checks.IgnoreStepsAnnotationList: "mock"})
typesClient := &mockTypesClient{
res: checkType,
}
ctx := context.TODO()
check := &mockCheck{
items: []any{"item"},
err: errors.New("run error, should not be triggered"),
}
obj := &advisorv0alpha1.Check{}
obj.SetAnnotations(map[string]string{})
meta, err := utils.MetaAccessor(obj)
if err != nil {
t.Fatal(err)
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
err = processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
assert.Equal(t, checks.StatusAnnotationProcessed, obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, "mock", obj.GetAnnotations()[checks.IgnoreStepsAnnotationList])
}
func TestProcessCheck_RunRecoversFromPanic(t *testing.T) {
@ -139,6 +169,7 @@ func TestProcessCheck_RunRecoversFromPanic(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{
@ -146,10 +177,10 @@ func TestProcessCheck_RunRecoversFromPanic(t *testing.T) {
runPanics: true,
}
err = processCheck(ctx, logging.DefaultLogger, client, obj, check)
err = processCheck(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.Error(t, err)
assert.Contains(t, err.Error(), "panic recovered in step")
assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationError, obj.GetAnnotations()[checks.StatusAnnotation])
}
func TestProcessCheckRetry_NoRetry(t *testing.T) {
@ -161,11 +192,12 @@ func TestProcessCheckRetry_NoRetry(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{}
err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
err = processCheckRetry(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
}
@ -173,7 +205,7 @@ func TestProcessCheckRetry_RetryError(t *testing.T) {
obj := &advisorv0alpha1.Check{}
obj.SetAnnotations(map[string]string{
checks.RetryAnnotation: "item",
checks.StatusAnnotation: "processed",
checks.StatusAnnotation: checks.StatusAnnotationProcessed,
})
meta, err := utils.MetaAccessor(obj)
if err != nil {
@ -181,6 +213,7 @@ func TestProcessCheckRetry_RetryError(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{
@ -188,16 +221,16 @@ func TestProcessCheckRetry_RetryError(t *testing.T) {
err: errors.New("retry error"),
}
err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
err = processCheckRetry(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.Error(t, err)
assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationError, obj.GetAnnotations()[checks.StatusAnnotation])
}
func TestProcessCheckRetry_Success(t *testing.T) {
obj := &advisorv0alpha1.Check{}
obj.SetAnnotations(map[string]string{
checks.RetryAnnotation: "item",
checks.StatusAnnotation: "processed",
checks.StatusAnnotation: checks.StatusAnnotationProcessed,
})
obj.CheckStatus.Report.Failures = []advisorv0alpha1.CheckReportFailure{
{
@ -211,15 +244,16 @@ func TestProcessCheckRetry_Success(t *testing.T) {
}
meta.SetCreatedBy("user:1")
client := &mockClient{}
typesClient := &mockTypesClient{}
ctx := context.TODO()
check := &mockCheck{
items: []any{"item"},
}
err = processCheckRetry(ctx, logging.DefaultLogger, client, obj, check)
err = processCheckRetry(ctx, logging.DefaultLogger, client, typesClient, obj, check)
assert.NoError(t, err)
assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation])
assert.Equal(t, checks.StatusAnnotationProcessed, obj.GetAnnotations()[checks.StatusAnnotation])
assert.Empty(t, obj.GetAnnotations()[checks.RetryAnnotation])
assert.Empty(t, obj.CheckStatus.Report.Failures)
}
@ -234,6 +268,18 @@ func (m *mockClient) PatchInto(ctx context.Context, id resource.Identifier, req
return nil
}
type mockTypesClient struct {
resource.Client
res resource.Object
}
func (m *mockTypesClient) Get(ctx context.Context, id resource.Identifier) (resource.Object, error) {
if m.res == nil {
return advisorv0alpha1.CheckTypeKind().ZeroValue(), nil
}
return m.res, nil
}
type mockCheck struct {
err error
items []any

@ -97,6 +97,21 @@ const injectedRtkApi = api
}),
providesTags: ['CheckType'],
}),
updateCheckType: build.mutation<UpdateCheckTypeApiResponse, UpdateCheckTypeApiArg>({
query: (queryArg) => ({
url: `/checktypes/${queryArg.name}`,
method: 'PATCH',
body: queryArg.patch,
params: {
pretty: queryArg.pretty,
dryRun: queryArg.dryRun,
fieldManager: queryArg.fieldManager,
fieldValidation: queryArg.fieldValidation,
force: queryArg.force,
},
}),
invalidatesTags: ['CheckType'],
}),
}),
overrideExisting: false,
});
@ -246,6 +261,22 @@ export type ListCheckTypeApiArg = {
/** Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. */
watch?: boolean;
};
export type UpdateCheckTypeApiResponse = /** status 200 OK */ CheckType | /** status 201 Created */ CheckType;
export type UpdateCheckTypeApiArg = {
/** name of the CheckType */
name: string;
/** If 'true', then the output is pretty printed. Defaults to 'false' unless the user-agent indicates a browser or command-line HTTP tool (curl and wget). */
pretty?: string;
/** When present, indicates that modifications should not be persisted. An invalid or unrecognized dryRun directive will result in an error response and no further processing of the request. Valid values are: - All: all dry run stages will be processed */
dryRun?: string;
/** fieldManager is a name associated with the actor or entity that is making these changes. The value must be less than or 128 characters long, and only contain printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint. This field is required for apply requests (application/apply-patch) but optional for non-apply patch types (JsonPatch, MergePatch, StrategicMergePatch). */
fieldManager?: string;
/** fieldValidation instructs the server on how to handle objects in the request (POST/PUT/PATCH) containing unknown or duplicate fields. Valid values are: - Ignore: This will ignore any unknown fields that are silently dropped from the object, and will ignore all but the last duplicate field that the decoder encounters. This is the default behavior prior to v1.23. - Warn: This will send a warning via the standard warning response header for each unknown field that is dropped from the object, and for each duplicate field that is encountered. The request will still succeed if there are no other errors, and will only persist the last of any duplicate fields. This is the default in v1.23+ - Strict: This will fail the request with a BadRequest error if any unknown fields would be dropped from the object, or if any duplicate fields are present. The error returned from the server will contain all unknown and duplicate fields encountered. */
fieldValidation?: string;
/** Force is going to "force" Apply requests. It means user will re-acquire conflicting fields owned by other people. Force flag must be unset for non-apply patch requests. */
force?: boolean;
patch: Patch;
};
export type Time = string;
export type FieldsV1 = object;
export type ManagedFieldsEntry = {

@ -15,6 +15,18 @@ export const advisorAPI = generatedAPI.enhanceEndpoints({
});
}
},
updateCheckType: (endpointDefinition) => {
const originalQuery = endpointDefinition.query;
if (originalQuery) {
endpointDefinition.query = (requestOptions) => ({
...originalQuery(requestOptions),
headers: {
'Content-Type': 'application/json-patch+json',
},
body: JSON.stringify(requestOptions.patch),
});
}
},
},
});
export const {
@ -24,5 +36,6 @@ export const {
useDeleteCheckMutation,
useUpdateCheckMutation,
useListCheckTypeQuery,
useUpdateCheckTypeMutation,
} = advisorAPI;
export { type Check, type CheckType } from './endpoints.gen'; // eslint-disable-line

@ -63,7 +63,15 @@ const config: ConfigFile = {
'../public/app/api/clients/advisor/endpoints.gen.ts': {
apiFile: '../public/app/api/clients/advisor/baseAPI.ts',
schemaFile: '../data/openapi/advisor.grafana.app-v0alpha1.json',
filterEndpoints: ['createCheck', 'getCheck', 'listCheck', 'deleteCheck', 'updateCheck', 'listCheckType'],
filterEndpoints: [
'createCheck',
'getCheck',
'listCheck',
'deleteCheck',
'updateCheck',
'listCheckType',
'updateCheckType',
],
tag: true,
},
'../public/app/api/clients/playlist/endpoints.gen.ts': {

Loading…
Cancel
Save