Advisor: RBAC revamp (#115151)
Co-authored-by: Todd Treece <todd.treece@grafana.com>
This commit is contained in:
co-authored by
Todd Treece
parent
1f4f2b4d7c
commit
a4eb98b4ed
@@ -162,6 +162,7 @@ var serviceIdentityTokenPermissions = []string{
|
||||
"collections.grafana.app:*", // user stars
|
||||
"plugins.grafana.app:*",
|
||||
"historian.alerting.grafana.app:*",
|
||||
"advisor.grafana.app:*",
|
||||
|
||||
// Secrets Manager uses a custom verb for secret decryption, and its authorizer does not allow wildcard permissions.
|
||||
"secret.grafana.app/securevalues:decrypt",
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
package advisor
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
)
|
||||
|
||||
const (
|
||||
// Check
|
||||
ActionAdvisorCheckCreate = "advisor.checks:create" // CREATE.
|
||||
ActionAdvisorCheckWrite = "advisor.checks:write" // UPDATE.
|
||||
ActionAdvisorCheckRead = "advisor.checks:read" // GET + LIST.
|
||||
ActionAdvisorCheckDelete = "advisor.checks:delete" // DELETE.
|
||||
|
||||
// CheckTypes
|
||||
ActionAdvisorCheckTypesCreate = "advisor.checktypes:create" // CREATE.
|
||||
ActionAdvisorCheckTypesWrite = "advisor.checktypes:write" // UPDATE.
|
||||
ActionAdvisorCheckTypesRead = "advisor.checktypes:read" // GET + LIST.
|
||||
ActionAdvisorCheckTypesDelete = "advisor.checktypes:delete" // DELETE.
|
||||
|
||||
// Register
|
||||
ActionAdvisorRegisterCreate = "advisor.register:create" // CREATE (register check types).
|
||||
)
|
||||
|
||||
var (
|
||||
ScopeProviderAdvisorCheck = accesscontrol.NewScopeProvider("advisor.checks")
|
||||
ScopeProviderAdvisorCheckTypes = accesscontrol.NewScopeProvider("advisor.checktypes")
|
||||
ScopeProviderAdvisorRegister = accesscontrol.NewScopeProvider("advisor.register")
|
||||
|
||||
ScopeAllAdvisorCheck = ScopeProviderAdvisorCheck.GetResourceAllScope()
|
||||
ScopeAllAdvisorCheckTypes = ScopeProviderAdvisorCheckTypes.GetResourceAllScope()
|
||||
ScopeAllAdvisorRegister = ScopeProviderAdvisorRegister.GetResourceAllScope()
|
||||
)
|
||||
|
||||
func registerAccessControlRoles(service accesscontrol.Service) error {
|
||||
// Check
|
||||
checkReader := accesscontrol.RoleRegistration{
|
||||
Role: accesscontrol.RoleDTO{
|
||||
Name: "fixed:advisor.checks:reader",
|
||||
DisplayName: "Advisor Check Reader",
|
||||
Description: "Read and list advisor checks.",
|
||||
Group: "Advisor",
|
||||
Permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: ActionAdvisorCheckRead,
|
||||
Scope: ScopeAllAdvisorCheck,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleAdmin)},
|
||||
}
|
||||
|
||||
checkWriter := accesscontrol.RoleRegistration{
|
||||
Role: accesscontrol.RoleDTO{
|
||||
Name: "fixed:advisor.checks:writer",
|
||||
DisplayName: "Advisor Check Writer",
|
||||
Description: "Create, update and delete advisor checks.",
|
||||
Group: "Advisor",
|
||||
Permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: ActionAdvisorCheckCreate,
|
||||
Scope: ScopeAllAdvisorCheck,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckRead,
|
||||
Scope: ScopeAllAdvisorCheck,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckWrite,
|
||||
Scope: ScopeAllAdvisorCheck,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckDelete,
|
||||
Scope: ScopeAllAdvisorCheck,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleAdmin)},
|
||||
}
|
||||
|
||||
// CheckTypes
|
||||
checkTypesReader := accesscontrol.RoleRegistration{
|
||||
Role: accesscontrol.RoleDTO{
|
||||
Name: "fixed:advisor.checktypes:reader",
|
||||
DisplayName: "Advisor Check Types Reader",
|
||||
Description: "Read and list advisor check types.",
|
||||
Group: "Advisor",
|
||||
Permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: ActionAdvisorCheckTypesRead,
|
||||
Scope: ScopeAllAdvisorCheckTypes,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleAdmin)},
|
||||
}
|
||||
|
||||
checkTypesWriter := accesscontrol.RoleRegistration{
|
||||
Role: accesscontrol.RoleDTO{
|
||||
Name: "fixed:advisor.checktypes:writer",
|
||||
DisplayName: "Advisor Check Types Writer",
|
||||
Description: "Create, update and delete advisor check types.",
|
||||
Group: "Advisor",
|
||||
Permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: ActionAdvisorCheckTypesCreate,
|
||||
Scope: ScopeAllAdvisorCheckTypes,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckTypesRead,
|
||||
Scope: ScopeAllAdvisorCheckTypes,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckTypesWrite,
|
||||
Scope: ScopeAllAdvisorCheckTypes,
|
||||
},
|
||||
{
|
||||
Action: ActionAdvisorCheckTypesDelete,
|
||||
Scope: ScopeAllAdvisorCheckTypes,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleAdmin)},
|
||||
}
|
||||
|
||||
// Register
|
||||
registerWriter := accesscontrol.RoleRegistration{
|
||||
Role: accesscontrol.RoleDTO{
|
||||
Name: "fixed:advisor.register:writer",
|
||||
DisplayName: "Advisor Register Writer",
|
||||
Description: "Register default advisor check types.",
|
||||
Group: "Advisor",
|
||||
Permissions: []accesscontrol.Permission{
|
||||
{
|
||||
Action: ActionAdvisorRegisterCreate,
|
||||
Scope: ScopeAllAdvisorRegister,
|
||||
},
|
||||
},
|
||||
},
|
||||
Grants: []string{string(org.RoleAdmin)},
|
||||
}
|
||||
|
||||
return service.DeclareFixedRoles(
|
||||
checkReader,
|
||||
checkWriter,
|
||||
checkTypesReader,
|
||||
checkTypesWriter,
|
||||
registerWriter,
|
||||
)
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
package advisor
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana-app-sdk/app"
|
||||
"fmt"
|
||||
|
||||
authlib "github.com/grafana/authlib/types"
|
||||
appsdkapiserver "github.com/grafana/grafana-app-sdk/k8s/apiserver"
|
||||
"github.com/grafana/grafana-app-sdk/simple"
|
||||
advisorapi "github.com/grafana/grafana/apps/advisor/pkg/apis"
|
||||
advisorapp "github.com/grafana/grafana/apps/advisor/pkg/app"
|
||||
"github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/appinstaller"
|
||||
grafanaauthorizer "github.com/grafana/grafana/pkg/services/apiserver/auth/authorizer"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -20,37 +20,26 @@ var (
|
||||
)
|
||||
|
||||
type AdvisorAppInstaller struct {
|
||||
appsdkapiserver.AppInstaller
|
||||
}
|
||||
|
||||
// GetAuthorizer returns the authorizer for the plugins app.
|
||||
func (a *AdvisorAppInstaller) GetAuthorizer() authorizer.Authorizer {
|
||||
return advisorapp.GetAuthorizer()
|
||||
*advisorapp.AdvisorAppInstaller
|
||||
}
|
||||
|
||||
func ProvideAppInstaller(
|
||||
accessControlService accesscontrol.Service,
|
||||
accessClient authlib.AccessClient,
|
||||
checkRegistry checkregistry.CheckService,
|
||||
cfg *setting.Cfg,
|
||||
orgService org.Service,
|
||||
) (*AdvisorAppInstaller, error) {
|
||||
provider := simple.NewAppProvider(advisorapi.LocalManifest(), nil, advisorapp.New)
|
||||
pluginConfig := cfg.PluginSettings["grafana-advisor-app"]
|
||||
specificConfig := checkregistry.AdvisorAppConfig{
|
||||
CheckRegistry: checkRegistry,
|
||||
PluginConfig: pluginConfig,
|
||||
StackID: cfg.StackID,
|
||||
OrgService: orgService,
|
||||
if err := registerAccessControlRoles(accessControlService); err != nil {
|
||||
return nil, fmt.Errorf("registering access control roles: %w", err)
|
||||
}
|
||||
appCfg := app.Config{
|
||||
KubeConfig: rest.Config{},
|
||||
ManifestData: *advisorapi.LocalManifest().ManifestData,
|
||||
SpecificConfig: specificConfig,
|
||||
}
|
||||
installer := &AdvisorAppInstaller{}
|
||||
i, err := appsdkapiserver.NewDefaultAppInstaller(provider, appCfg, advisorapi.NewGoTypeAssociator())
|
||||
|
||||
authorizer := grafanaauthorizer.NewResourceAuthorizer(accessClient)
|
||||
i, err := advisorapp.ProvideAppInstaller(authorizer, checkRegistry, cfg, orgService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
installer.AppInstaller = i
|
||||
return installer, nil
|
||||
return &AdvisorAppInstaller{
|
||||
AdvisorAppInstaller: i,
|
||||
}, nil
|
||||
}
|
||||
|
||||
Generated
+2
-2
@@ -819,7 +819,7 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
|
||||
return nil, err
|
||||
}
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, managedpluginsNoop, noop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller(checkregistryService, cfg, orgService)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller(acimplService, accessClient, checkregistryService, cfg, orgService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1480,7 +1480,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
|
||||
return nil, err
|
||||
}
|
||||
checkregistryService := checkregistry.ProvideService(service15, pluginstoreService, plugincontextProvider, middlewareHandler, plugincheckerService, repoManager, preinstallImpl, managedpluginsNoop, noop, ssosettingsimplService, cfg, pluginerrsStore)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller(checkregistryService, cfg, orgService)
|
||||
advisorAppInstaller, err := advisor2.ProvideAppInstaller(acimplService, accessClient, checkregistryService, cfg, orgService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -86,6 +86,9 @@ func newPermissionRegistry() *permissionRegistry {
|
||||
"plugins": "plugins:id:",
|
||||
"plugins.plugins": "plugins.plugins:uid:",
|
||||
"plugins.metas": "plugins.metas:uid:",
|
||||
"advisor.checks": "advisor.checks:uid:",
|
||||
"advisor.checktypes": "advisor.checktypes:uid:",
|
||||
"advisor.register": "advisor.register:uid:",
|
||||
"provisioners": "provisioners:",
|
||||
"reports": "reports:id:",
|
||||
"permissions": "permissions:type:",
|
||||
|
||||
@@ -301,6 +301,11 @@ func NewMapperRegistry() MapperRegistry {
|
||||
"plugins": newResourceTranslation("plugins.plugins", "uid", false, nil),
|
||||
"metas": newResourceTranslation("plugins.metas", "uid", false, nil),
|
||||
},
|
||||
"advisor.grafana.app": {
|
||||
"checks": newResourceTranslation("advisor.checks", "uid", false, nil),
|
||||
"checktypes": newResourceTranslation("advisor.checktypes", "uid", false, nil),
|
||||
"register": newResourceTranslation("advisor.register", "uid", false, nil),
|
||||
},
|
||||
})
|
||||
|
||||
return mapper
|
||||
|
||||
Reference in New Issue
Block a user