* [API Server] Add Example App for reference use. * Remove Printlns. * Upgrade app-sdk to v0.46.0, update apps to handle breaking changes. * Only start the reconciler for the example app if the v1alpha1 API version is enabled. * Some comment doc updates. * Run make update-workspace * Set codeowner for /apps/example * Run make gofmt and make update-workspace * Run prettier on apps/example/README.md * Add COPY apps/example to Dockerfile * Add an authorizer to the example app. * Fix import ordering. * Update apps/example/kinds/manifest.cue Co-authored-by: Owen Diehl <ow.diehl@gmail.com> * Run make update-workspace * Re-run make gen-go for enterprise import updates * Run make update-workspace --------- Co-authored-by: Owen Diehl <ow.diehl@gmail.com>
56 lines
1.7 KiB
Go
56 lines
1.7 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"regexp"
|
|
|
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
|
|
|
"github.com/grafana/grafana/apps/example/pkg/apis/example/v1alpha1"
|
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
|
)
|
|
|
|
var namespacedSomethingRouteMatcher = regexp.MustCompile(fmt.Sprintf(`^/apis/%s/%s/namespaces/([^\/]+)/something$`, v1alpha1.APIGroup, v1alpha1.APIVersion))
|
|
|
|
// GetAuthorizer returns an authorizer for all kinds managed by the example app.
|
|
// It must be added to the installer in pkg/registry/apps/example/register.go to be used
|
|
func GetAuthorizer() authorizer.Authorizer {
|
|
return authorizer.AuthorizerFunc(
|
|
func(ctx context.Context, attr authorizer.Attributes) (authorizer.Decision, string, error) {
|
|
if !attr.IsResourceRequest() {
|
|
return authorizer.DecisionNoOpinion, "", nil
|
|
}
|
|
|
|
// require a user
|
|
u, err := identity.GetRequester(ctx)
|
|
if err != nil {
|
|
return authorizer.DecisionDeny, "valid user is required", err
|
|
}
|
|
|
|
// check if is admin
|
|
if u.GetIsGrafanaAdmin() {
|
|
return authorizer.DecisionAllow, "", nil
|
|
}
|
|
|
|
// Only allow admins to call the custom subresource
|
|
if attr.GetSubresource() == "custom" {
|
|
return authorizer.DecisionDeny, "forbidden", nil
|
|
}
|
|
|
|
// Only allow admins to call the namespaced and cluster routes
|
|
// There's no easy way to check that from attrs like with GetSubresource(),
|
|
// so we look at the full path and check
|
|
if namespacedSomethingRouteMatcher.MatchString(attr.GetPath()) {
|
|
return authorizer.DecisionDeny, "forbidden", nil
|
|
}
|
|
if attr.GetPath() == fmt.Sprintf("/apis/%s/%s/other", v1alpha1.APIGroup, v1alpha1.APIVersion) {
|
|
return authorizer.DecisionDeny, "forbidden", nil
|
|
}
|
|
|
|
// Otherwise, allow
|
|
return authorizer.DecisionAllow, "", nil
|
|
},
|
|
)
|
|
}
|