Code Diff
diff --git a/pkg/registry/apis/iam/datasourcek8s/k8s.go b/pkg/registry/apis/iam/datasourcek8s/k8s.go
index 1c9c247b6ad60..ec5aaac6c8330 100644
--- a/pkg/registry/apis/iam/datasourcek8s/k8s.go
+++ b/pkg/registry/apis/iam/datasourcek8s/k8s.go
@@ -41,13 +41,33 @@ func LegacyVerbToK8sAction(dsType, legacyVerb string) string {
}
}
+// legacyActionToK8s converts a legacy datasource action to its k8s form.
+// It handles the resource-permissions actions (datasources.permissions:read/write)
+// and the plain datasource verbs (datasources:read/write/…). Returns the converted
+// action and whether a conversion was applied.
+func legacyActionToK8s(dsType, action string) (string, bool) {
+ if permVerb, ok := strings.CutPrefix(action, "datasources.permissions:"); ok {
+ switch permVerb {
+ case "read":
+ return K8sDatasourceAPIGroup(dsType) + "/datasources:get_permissions", true
+ case "write":
+ return K8sDatasourceAPIGroup(dsType) + "/datasources:set_permissions", true
+ default:
+ return action, false
+ }
+ }
+ legacyVerb, ok := strings.CutPrefix(action, "datasources:")
+ if !ok || strings.Contains(legacyVerb, ":") {
+ return action, false
+ }
+ return LegacyVerbToK8sAction(dsType, legacyVerb), true
+}
+
// LegacyDatasourceAction replaces a legacy ds action string with its k8s form
func LegacyDatasourceAction(dsType string, action *string) {
- legacyVerb, ok := strings.CutPrefix(*action, "datasources:")
- if !ok || strings.Contains(legacyVerb, ":") {
- return
+ if converted, ok := legacyActionToK8s(dsType, *action); ok {
+ *action = converted
}
- *action = LegacyVerbToK8sAction(dsType, legacyVerb)
}
// LegacyDatasourceScopeAndActionToK8s converts legacy datasource scope and action to k8s form
@@ -58,8 +78,8 @@ func LegacyDatasourceScopeAndActionToK8s(datasourceType, scope, action string) (
if uid, ok := strings.CutPrefix(scope, "datasources:uid:"); ok {
scope = LegacyUIDScopeToK8s(datasourceType, uid)
}
- if legacyVerb, ok := strings.CutPrefix(action, "datasources:"); ok {
- action = LegacyVerbToK8sAction(datasourceType, legacyVerb)
+ if converted, ok := legacyActionToK8s(datasourceType, action); ok {
+ action = converted
}
return scope, action
}
diff --git a/pkg/registry/apis/iam/datasourcek8s/k8s_test.go b/pkg/registry/apis/iam/datasourcek8s/k8s_test.go
index a8e343080403c..d6b1acb089d57 100644
--- a/pkg/registry/apis/iam/datasourcek8s/k8s_test.go
+++ b/pkg/registry/apis/iam/datasourcek8s/k8s_test.go
@@ -46,9 +46,19 @@ func TestLegacyDatasourceAction(t *testing.T) {
LegacyDatasourceAction("loki", &a)
assert.Equal(t, "loki.datasource.grafana.app/datasources:get", a)
})
- t.Run("skips nested resource", func(t *testing.T) {
+ t.Run("maps permissions read", func(t *testing.T) {
a := "datasources.permissions:read"
LegacyDatasourceAction("loki", &a)
- assert.Equal(t, "datasources.permissions:read", a)
+ assert.Equal(t, "loki.datasource.grafana.app/datasources:get_permissions", a)
+ })
+ t.Run("maps permissions write", func(t *testing.T) {
+ a := "datasources.permissions:write"
+ LegacyDatasourceAction("*", &a)
+ assert.Equal(t, "*.datasource.grafana.app/datasources:set_permissions", a)
+ })
+ t.Run("skips unknown nested resource", func(t *testing.T) {
+ a := "datasources.id:read"
+ LegacyDatasourceAction("loki", &a)
+ assert.Equal(t, "datasources.id:read", a)
})
}
diff --git a/pkg/registry/apis/iam/datasourcek8s/legacy.go b/pkg/registry/apis/iam/datasourcek8s/legacy.go
index 4c969dcb4095a..d925833d1936d 100644
--- a/pkg/registry/apis/iam/datasourcek8s/legacy.go
+++ b/pkg/registry/apis/iam/datasourcek8s/legacy.go
@@ -30,6 +30,10 @@ func K8sDSActionToLegacy(action string) (string, bool) {
return "datasources:write", true
case "delete":
return "datasources:delete", true
+ case "get_permissions":
+ return "datasources.permissions:read", true
+ case "set_permissions":
+ return "datasources.permissions:write", true
default:
return "", false
}
diff --git a/pkg/registry/apis/iam/datasourcek8s/legacy_test.go b/pkg/registry/apis/iam/datasourcek8s/legacy_test.go
index 23aacb3672e37..158c13e4bd176 100644
--- a/pkg/registry/apis/iam/datasourcek8s/legacy_test.go
+++ b/pkg/registry/apis/iam/datasourcek8s/legacy_test.go
@@ -79,6 +79,18 @@ func TestK8sDSActionToLegacy(t *testing.T) {
expectedAction: "datasources:read",
expectedOk: true,
},
+ {
+ name: "datasource api group get_permissions verb",
+ action: "loki.datasource.grafana.app/datasources:get_permissions",
+ expectedAction: "datasources.permissions:read",
+ expectedOk: true,
+ },
+ {
+ name: "datasource api group set_permissions verb",
+ action: "*.datasource.grafana.app/datasources:set_permissions",
+ expectedAction: "datasources.permissions:write",
+ expectedOk: true,
+ },
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {