LBAC for datasources: GA (#99511)

* GA: feature toggle removal of `teamHttpHeaders`

* Apply suggestions from code review

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>

---------

Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com>
Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
pull/100986/head
Eric Leijonmarck 11 months ago committed by GitHub
parent 6dae264a06
commit 32643c933e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/index.md
  2. 2
      docs/sources/administration/data-source-management/teamlbac/create-teamlbac-rules/index.md
  3. 1
      docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md
  4. 1
      packages/grafana-data/src/types/featureToggles.gen.ts
  5. 9
      pkg/api/datasources.go
  6. 2
      pkg/api/datasources_test.go
  7. 2
      pkg/services/datasources/service/datasource.go
  8. 8
      pkg/services/datasources/service/datasource_test.go
  9. 9
      pkg/services/featuremgmt/registry.go
  10. 1
      pkg/services/featuremgmt/toggles_gen.csv
  11. 4
      pkg/services/featuremgmt/toggles_gen.go
  12. 1
      pkg/services/featuremgmt/toggles_gen.json

@ -22,11 +22,17 @@ You cannot configure LBAC rules for Grafana-provisioned data sources from the UI
## Before you begin
To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. Contact support to enable the feature toggle for you.
To be able to use LBAC for Prometheus data sources, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. Contact support to enable the feature toggle for you.
- Be sure that you have the permission setup to create a Prometheus tenant in Grafana Cloud
- Be sure that you have admin data source permissions for Grafana.
## Grafana Cloud
LBAC for data sources is available in private preview on Grafana Cloud for Prometheus created with basic authentication. Prometheus data sources for LBAC for data sources can only be created, provisioning is currently not available.
You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. We recommend that you replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for New Prometheus Data Source](https://grafana.com/docs/grafana/latest/administration/data-source-management/teamlbac/configure-teamlbac-for-Prometheus/#task-1-lbac-configuration-for-new-Prometheus-data-source) and then add the LBAC configuration to the new data source.
### Permissions
We recommend that you remove all permissions for roles and teams that are not required to access the data source. This will help to ensure that only the required teams have access to the data source. The recommended permissions are `Admin` permission and only add the teams `Query` permissions that you want to add LBAC for data sources rules for.
@ -57,7 +63,7 @@ You cannot configure LBAC rules for Grafana-provisioned data sources from the UI
## Before you begin
To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you.
To be able to use LBAC for Prometheus data sources, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. Contact support to enable the feature toggle for you.
- Be sure that you have the permission setup to create a cluster in your Grafana
- Be sure that you have admin plugins permissions for Grafana.

@ -17,8 +17,6 @@ LBAC for data sources is available for LBAC-supported data sources created with
## Before you begin
To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you.
- Be sure that you have the permission setup to create a Loki tenant in Grafana Cloud.
- Be sure that you have admin data source permissions for Grafana.
- Be sure that you have a team setup in Grafana.

@ -107,7 +107,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
| `reportingRetries` | Enables rendering retries for the reporting feature |
| `externalServiceAccounts` | Automatic service account and token setup for plugins |
| `cloudWatchBatchQueries` | Runs CloudWatch metrics queries as separate batches |
| `teamHttpHeaders` | Enables LBAC for datasources to apply LogQL filtering of logs to the client requests for users in teams |
| `pdfTables` | Enables generating table data as PDF in reporting |
| `canvasPanelPanZoom` | Allow pan and zoom in canvas panel |
| `regressionTransformation` | Enables regression analysis transformation |

@ -117,7 +117,6 @@ export interface FeatureToggles {
cloudWatchBatchQueries?: boolean;
recoveryThreshold?: boolean;
lokiStructuredMetadata?: boolean;
teamHttpHeaders?: boolean;
cachingOptimizeSerializationMemoryUsage?: boolean;
prometheusPromQAIL?: boolean;
prometheusCodeModeMetricNamesSearch?: boolean;

@ -20,7 +20,6 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -394,11 +393,9 @@ func (hs *HTTPServer) AddDataSource(c *contextmodel.ReqContext) response.Respons
// It's forbidden to update the rules from the datasource api.
// team HTTP headers update have to be done through `updateDatasourceLBACRules`
if hs.Features != nil && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagTeamHttpHeaders) {
if cmd.JsonData != nil {
if _, ok := cmd.JsonData.CheckGet("teamHttpHeaders"); ok {
return response.Error(http.StatusForbidden, "Cannot create datasource with team HTTP headers, need to use updateDatasourceLBACRules API", nil)
}
if cmd.JsonData != nil {
if _, ok := cmd.JsonData.CheckGet("teamHttpHeaders"); ok {
return response.Error(http.StatusForbidden, "Cannot create datasource with team HTTP headers, need to use updateDatasourceLBACRules API", nil)
}
}

@ -229,7 +229,7 @@ func TestAddDataSourceTeamHTTPHeaders(t *testing.T) {
expectedDatasource: &datasources.DataSource{},
},
Cfg: setting.NewCfg(),
Features: featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders),
Features: featuremgmt.WithFeatures(),
accesscontrolService: actest.FakeService{},
AccessControl: actest.FakeAccessControl{
ExpectedEvaluate: true,

@ -536,7 +536,7 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *datasources.UpdateD
// preserve existing lbac rules when updating datasource if we're not updating lbac rules
// TODO: Refactor to store lbac rules separate from a datasource
if s.features != nil && s.features.IsEnabled(ctx, featuremgmt.FlagTeamHttpHeaders) && !cmd.AllowLBACRuleUpdates {
if !cmd.AllowLBACRuleUpdates {
s.logger.Debug("Overriding LBAC rules with stored ones using updateLBACRules API",
"reason", "overriding_lbac_rules_from_datasource_api",
"datasource_id", dataSource.ID,

@ -572,7 +572,7 @@ func TestService_UpdateDataSource(t *testing.T) {
t.Run("Should update LBAC rules when updating from API", func(t *testing.T) {
dsService := initDSService(t)
dsService.features = featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders)
dsService.features = featuremgmt.WithFeatures()
// Create a datasource with existing LBAC rules
existingRules := []interface{}{
@ -629,7 +629,7 @@ func TestService_UpdateDataSource(t *testing.T) {
})
t.Run("Should preserve LBAC rules when not updating from API", func(t *testing.T) {
dsService := initDSService(t)
dsService.features = featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders)
dsService.features = featuremgmt.WithFeatures()
// Create a datasource with existing LBAC rules
existingRules := []interface{}{
map[string]interface{}{
@ -680,7 +680,7 @@ func TestService_UpdateDataSource(t *testing.T) {
t.Run("Should not remove stored rules without AllowLBACRuleUpdates", func(t *testing.T) {
dsService := initDSService(t)
dsService.features = featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders)
dsService.features = featuremgmt.WithFeatures()
// Create a datasource with existing LBAC rules
existingRules := []interface{}{
@ -720,7 +720,7 @@ func TestService_UpdateDataSource(t *testing.T) {
t.Run("Should not populate empty stored rules without AllowLBACRuleUpdates", func(t *testing.T) {
dsService := initDSService(t)
dsService.features = featuremgmt.WithFeatures(featuremgmt.FlagTeamHttpHeaders)
dsService.features = featuremgmt.WithFeatures()
// Create a datasource with empty LBAC rules
jsonData := simplejson.New()

@ -743,15 +743,6 @@ var (
Owner: grafanaObservabilityLogsSquad,
Expression: "true",
},
{
Name: "teamHttpHeaders",
Description: "Enables LBAC for datasources to apply LogQL filtering of logs to the client requests for users in teams",
Stage: FeatureStagePublicPreview,
FrontendOnly: false,
AllowSelfServe: true,
Owner: identityAccessTeam,
Expression: "true",
},
{
Name: "cachingOptimizeSerializationMemoryUsage",
Description: "If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses.",

@ -98,7 +98,6 @@ queryServiceFromUI,experimental,@grafana/grafana-app-platform-squad,false,false,
cloudWatchBatchQueries,preview,@grafana/aws-datasources,false,false,false
recoveryThreshold,GA,@grafana/alerting-squad,false,true,false
lokiStructuredMetadata,GA,@grafana/observability-logs,false,false,false
teamHttpHeaders,preview,@grafana/identity-access-team,false,false,false
cachingOptimizeSerializationMemoryUsage,experimental,@grafana/grafana-operator-experience-squad,false,false,false
prometheusPromQAIL,experimental,@grafana/oss-big-tent,false,false,true
prometheusCodeModeMetricNamesSearch,experimental,@grafana/oss-big-tent,false,false,true

1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
98 cloudWatchBatchQueries preview @grafana/aws-datasources false false false
99 recoveryThreshold GA @grafana/alerting-squad false true false
100 lokiStructuredMetadata GA @grafana/observability-logs false false false
teamHttpHeaders preview @grafana/identity-access-team false false false
101 cachingOptimizeSerializationMemoryUsage experimental @grafana/grafana-operator-experience-squad false false false
102 prometheusPromQAIL experimental @grafana/oss-big-tent false false true
103 prometheusCodeModeMetricNamesSearch experimental @grafana/oss-big-tent false false true

@ -403,10 +403,6 @@ const (
// Enables the loki data source to request structured metadata from the Loki server
FlagLokiStructuredMetadata = "lokiStructuredMetadata"
// FlagTeamHttpHeaders
// Enables LBAC for datasources to apply LogQL filtering of logs to the client requests for users in teams
FlagTeamHttpHeaders = "teamHttpHeaders"
// FlagCachingOptimizeSerializationMemoryUsage
// If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses.
FlagCachingOptimizeSerializationMemoryUsage = "cachingOptimizeSerializationMemoryUsage"

@ -3846,6 +3846,7 @@
"name": "teamHttpHeaders",
"resourceVersion": "1738590709387",
"creationTimestamp": "2023-10-17T10:23:54Z",
"deletionTimestamp": "2025-02-19T10:48:55Z",
"annotations": {
"grafana.app/updatedTimestamp": "2025-02-03 13:51:49.3871 +0000 UTC"
}

Loading…
Cancel
Save