Skip to content

Commit

Permalink
User-configurable overrides: add scope query parameter to return merg…
Browse files Browse the repository at this point in the history
…ed overrides for tenant (#2915)

* User-configurable overrides: add scope query parameter to return merged overrides for tenant

* Update CHANGELOG.md

* Linting
  • Loading branch information
Koenraad Verheyden authored Sep 22, 2023
1 parent e5e1bc9 commit c031394
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* [ENHANCEMENT] Add span metrics filter policies to user-configurable overrides [#2906](https://github.com/grafana/tempo/pull/2906) (@rlankfo)
* [ENHANCEMENT] Add collection-interval to metrics-generator config in user-configurable overrides [#2899](https://github.com/grafana/tempo/pull/2899) (@rlankfo)
* [ENHANCEMENT] Add `target_info_excluded_dimensions` to user-config api [#2945](https://github.com/grafana/tempo/pull/2945) (@ie-pham)
* [ENHANCEMENT] User-configurable overrides: add scope query parameter to return merged overrides for tenant [#2915](https://github.com/grafana/tempo/pull/2915) (@kvrhdn)
* [BUGFIX] Fix panic in metrics summary api [#2738](https://github.com/grafana/tempo/pull/2738) (@mdisibio)
* [BUGFIX] Fix rare deadlock when uploading blocks to Azure Blob Storage [#2129](https://github.com/grafana/tempo/issues/2129) (@LasseHels)
* [BUGFIX] Only search ingester blocks that fall within the request time range. [#2783](https://github.com/grafana/tempo/pull/2783) (@joe-elliott)
Expand Down
4 changes: 2 additions & 2 deletions cmd/tempo/app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (t *App) initOverridesAPI() (services.Service, error) {
return services.NewIdleService(nil, nil), nil
}

userConfigOverridesAPI, err := userconfigurableoverridesapi.New(&cfg.Client, NewOverridesValidator(&t.cfg))
userConfigOverridesAPI, err := userconfigurableoverridesapi.New(&cfg.Client, t.Overrides, NewOverridesValidator(&t.cfg))
if err != nil {
return nil, errors.Wrap(err, "failed to create user-configurable overrides API")
}
Expand Down Expand Up @@ -537,7 +537,7 @@ func (t *App) setupModuleManager() error {
// InternalServer: nil,
Server: {InternalServer},
Overrides: {Server},
OverridesAPI: {Server},
OverridesAPI: {Server, Overrides},
MemberlistKV: {Server},
UsageReport: {MemberlistKV},
IngesterRing: {Server, MemberlistKV},
Expand Down
5 changes: 4 additions & 1 deletion modules/overrides/userconfigurable/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/opentracing/opentracing-go"
"github.com/pkg/errors"

"github.com/grafana/tempo/modules/overrides"
"github.com/grafana/tempo/modules/overrides/userconfigurable/client"
tempo_log "github.com/grafana/tempo/pkg/util/log"
"github.com/grafana/tempo/tempodb/backend"
Expand All @@ -30,19 +31,21 @@ type UserConfigOverridesAPI struct {
services.Service

client client.Client
overrides overrides.Interface
validator Validator

logger log.Logger
}

func New(config *client.Config, validator Validator) (*UserConfigOverridesAPI, error) {
func New(config *client.Config, overrides overrides.Interface, validator Validator) (*UserConfigOverridesAPI, error) {
client, err := client.New(config)
if err != nil {
return nil, err
}

api := &UserConfigOverridesAPI{
client: client,
overrides: overrides,
validator: validator,

logger: log.With(tempo_log.Logger, "component", "overrides-api"),
Expand Down
22 changes: 18 additions & 4 deletions modules/overrides/userconfigurable/api/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/grafana/tempo/modules/overrides"
"github.com/grafana/tempo/modules/overrides/userconfigurable/client"
"github.com/grafana/tempo/pkg/api"
"github.com/grafana/tempo/tempodb/backend"
Expand All @@ -26,8 +27,12 @@ func Test_UserConfigOverridesAPI_overridesHandlers(t *testing.T) {
Backend: backend.Local,
Local: &local.Config{Path: t.TempDir()},
}

o, err := overrides.NewOverrides(overrides.Config{})
assert.NoError(t, err)

validator := &mockValidator{}
overridesAPI, err := New(&cfg, validator)
overridesAPI, err := New(&cfg, o, validator)
require.NoError(t, err)

// Provision some data
Expand Down Expand Up @@ -171,10 +176,13 @@ func Test_UserConfigOverridesAPI_patchOverridesHandlers(t *testing.T) {
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
o, err := overrides.NewOverrides(overrides.Config{})
assert.NoError(t, err)

overridesAPI, err := New(&client.Config{
Backend: backend.Local,
Local: &local.Config{Path: t.TempDir()},
}, &mockValidator{})
}, o, &mockValidator{})
require.NoError(t, err)

if tc.current != "" {
Expand Down Expand Up @@ -203,10 +211,13 @@ func Test_UserConfigOverridesAPI_patchOverridesHandlers(t *testing.T) {
}

func TestUserConfigOverridesAPI_patchOverridesHandler_noVersionConflict(t *testing.T) {
o, err := overrides.NewOverrides(overrides.Config{})
assert.NoError(t, err)

overridesAPI, err := New(&client.Config{
Backend: backend.Local,
Local: &local.Config{Path: t.TempDir()},
}, &mockValidator{})
}, o, &mockValidator{})
require.NoError(t, err)

// inject our client
Expand Down Expand Up @@ -241,10 +252,13 @@ func TestUserConfigOverridesAPI_patchOverridesHandler_noVersionConflict(t *testi
}

func TestUserConfigOverridesAPI_patchOverridesHandler_versionConflict(t *testing.T) {
o, err := overrides.NewOverrides(overrides.Config{})
assert.NoError(t, err)

overridesAPI, err := New(&client.Config{
Backend: backend.Local,
Local: &local.Config{Path: t.TempDir()},
}, &mockValidator{})
}, o, &mockValidator{})
require.NoError(t, err)

// inject our client
Expand Down
53 changes: 53 additions & 0 deletions modules/overrides/userconfigurable/api/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"context"
"fmt"
"io"
"net/http"

Expand All @@ -14,8 +15,10 @@ import (
ot_log "github.com/opentracing/opentracing-go/log"
"github.com/pkg/errors"

"github.com/grafana/tempo/modules/overrides"
"github.com/grafana/tempo/modules/overrides/userconfigurable/client"
"github.com/grafana/tempo/pkg/api"
"github.com/grafana/tempo/pkg/spanfilter/config"
"github.com/grafana/tempo/tempodb/backend"
)

Expand All @@ -24,6 +27,10 @@ const (
headerIfMatch = "If-Match"

errNoIfMatchHeader = "must specify If-Match header"

queryParamScope = "scope"
scopeAPI = "api"
scopeMerged = "merged"
)

// GetHandler retrieves the user-configured overrides from the backend.
Expand All @@ -38,12 +45,24 @@ func (a *UserConfigOverridesAPI) GetHandler(w http.ResponseWriter, r *http.Reque
return
}

scope := scopeAPI
if value, ok := r.URL.Query()[queryParamScope]; ok {
scope = value[0]
}
if scope != scopeAPI && scope != scopeMerged {
http.Error(w, fmt.Sprintf("unknown scope \"%s\", valid options are api and merged", scope), http.StatusBadRequest)
}

limits, version, err := a.get(ctx, userID)
if err != nil {
writeError(w, err)
return
}

if scope == scopeMerged {
limits = limitsFromOverrides(a.overrides, userID)
}

err = writeLimits(w, limits, version)
}

Expand Down Expand Up @@ -176,3 +195,37 @@ func (a *UserConfigOverridesAPI) logRequest(ctx context.Context, handler string,
span.Finish()
}
}

func limitsFromOverrides(overrides overrides.Interface, userID string) *client.Limits {
return &client.Limits{
Forwarders: strArrPtr(overrides.Forwarders(userID)),
MetricsGenerator: &client.LimitsMetricsGenerator{
Processors: overrides.MetricsGeneratorProcessors(userID),
DisableCollection: boolPtr(overrides.MetricsGeneratorDisableCollection(userID)),
Processor: &client.LimitsMetricsGeneratorProcessor{
ServiceGraphs: &client.LimitsMetricsGeneratorProcessorServiceGraphs{
Dimensions: strArrPtr(overrides.MetricsGeneratorProcessorServiceGraphsDimensions(userID)),
EnableClientServerPrefix: boolPtr(overrides.MetricsGeneratorProcessorServiceGraphsEnableClientServerPrefix(userID)),
PeerAttributes: strArrPtr(overrides.MetricsGeneratorProcessorServiceGraphsPeerAttributes(userID)),
},
SpanMetrics: &client.LimitsMetricsGeneratorProcessorSpanMetrics{
Dimensions: strArrPtr(overrides.MetricsGeneratorProcessorSpanMetricsDimensions(userID)),
EnableTargetInfo: boolPtr(overrides.MetricsGeneratorProcessorSpanMetricsEnableTargetInfo(userID)),
FilterPolicies: filterPoliciesPtr(overrides.MetricsGeneratorProcessorSpanMetricsFilterPolicies(userID)),
},
},
},
}
}

func boolPtr(b bool) *bool {
return &b
}

func strArrPtr(s []string) *[]string {
return &s
}

func filterPoliciesPtr(p []config.FilterPolicy) *[]config.FilterPolicy {
return &p
}

0 comments on commit c031394

Please sign in to comment.