mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-24 16:17:11 +08:00
Fix resource kinds for search (#13142)
This commit is contained in:
@@ -424,12 +424,8 @@ const (
|
||||
// RequestableResourceKinds lists all Teleport resource kinds users can request access to.
|
||||
var RequestableResourceKinds = []string{
|
||||
KindNode,
|
||||
KindKubeService,
|
||||
KindKubernetesCluster,
|
||||
KindDatabaseServer,
|
||||
KindDatabase,
|
||||
KindAppServer,
|
||||
KindApp,
|
||||
KindWindowsDesktopService,
|
||||
KindWindowsDesktop,
|
||||
}
|
||||
|
||||
@@ -219,16 +219,35 @@ func (a *accessChecker) checkAllowedResources(r AccessCheckable) error {
|
||||
// resources, only role-based access control is used
|
||||
return nil
|
||||
}
|
||||
|
||||
// Note: logging in this function only happens in debug mode. This is because
|
||||
// adding logging to this function (which is called on every resource returned
|
||||
// by the backend) can slow down this function by 50x for large clusters!
|
||||
isDebugEnabled, debugf := rbacDebugLogger()
|
||||
|
||||
for _, resourceID := range a.info.AllowedResourceIDs {
|
||||
if resourceID.ClusterName == a.localCluster &&
|
||||
resourceID.Kind == r.GetKind() &&
|
||||
resourceID.Name == r.GetName() {
|
||||
// allowed to access this resource
|
||||
// Allowed to access this resource by resource ID, move on to role checks.
|
||||
if isDebugEnabled {
|
||||
debugf("Matched allowed resource ID %q", types.ResourceIDToString(resourceID))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return trace.AccessDenied("access to %s:%s is not allowed. Allowed resources: %v",
|
||||
r.GetKind(), r.GetName(), a.info.AllowedResourceIDs)
|
||||
|
||||
if isDebugEnabled {
|
||||
allowedResources, err := types.ResourceIDsToString(a.info.AllowedResourceIDs)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
err = trace.AccessDenied("access to %v denied, %q not in allowed resource IDs %s",
|
||||
r.GetKind(), r.GetName(), allowedResources)
|
||||
debugf("Access denied: %v", err)
|
||||
return err
|
||||
}
|
||||
return trace.AccessDenied("access to %v denied, not in allowed resource IDs", r.GetKind())
|
||||
}
|
||||
|
||||
// CheckAccess checks if the identity for this AccessChecker has access to the
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"github.com/gravitational/teleport"
|
||||
"github.com/gravitational/teleport/api/client"
|
||||
"github.com/gravitational/teleport/api/client/proto"
|
||||
apidefaults "github.com/gravitational/teleport/api/defaults"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/asciitable"
|
||||
"github.com/gravitational/teleport/lib/auth"
|
||||
@@ -377,17 +378,27 @@ func onRequestSearch(cf *CLIConf) error {
|
||||
clusterName := clusterNameResource.GetClusterName()
|
||||
|
||||
req := proto.ListResourcesRequest{
|
||||
ResourceType: cf.ResourceKind,
|
||||
ResourceType: searchKindFixup(cf.ResourceKind),
|
||||
Labels: tc.Labels,
|
||||
PredicateExpression: cf.PredicateExpression,
|
||||
SearchKeywords: tc.SearchKeywords,
|
||||
UseSearchAsRoles: true,
|
||||
}
|
||||
resources, err := client.GetResourcesWithFilters(cf.Context, authClient, req)
|
||||
|
||||
results, err := client.GetResourcesWithFilters(cf.Context, authClient, req)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
|
||||
var resources types.ResourcesWithLabels
|
||||
for _, result := range results {
|
||||
fixedResources, err := resultKindFixup(result, cf.ResourceKind)
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
resources = append(resources, fixedResources...)
|
||||
}
|
||||
|
||||
rows := [][]string{}
|
||||
var resourceIDs []string
|
||||
for _, resource := range resources {
|
||||
@@ -425,3 +436,44 @@ To request access to these resources, run
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func searchKindFixup(kind string) string {
|
||||
// Some resource kinds don't support search directly, run the search on the
|
||||
// parent kind instead.
|
||||
switch kind {
|
||||
case types.KindApp:
|
||||
return types.KindAppServer
|
||||
case types.KindDatabase:
|
||||
return types.KindDatabaseServer
|
||||
case types.KindKubernetesCluster:
|
||||
return types.KindKubeService
|
||||
default:
|
||||
return kind
|
||||
}
|
||||
}
|
||||
|
||||
func resultKindFixup(resource types.ResourceWithLabels, hint string) (types.ResourcesWithLabels, error) {
|
||||
// The inverse of searchKindFixup, after the search map the result back to
|
||||
// the kind we really want.
|
||||
switch r := resource.(type) {
|
||||
case types.AppServer:
|
||||
return types.ResourcesWithLabels{r.GetApp()}, nil
|
||||
case types.DatabaseServer:
|
||||
return types.ResourcesWithLabels{r.GetDatabase()}, nil
|
||||
case types.Server:
|
||||
if hint == types.KindKubernetesCluster {
|
||||
kubeClusters := r.GetKubernetesClusters()
|
||||
resources := make(types.ResourcesWithLabels, 0, len(kubeClusters))
|
||||
for _, kubeCluster := range kubeClusters {
|
||||
resource, err := types.NewKubernetesClusterV3FromLegacyCluster(apidefaults.Namespace, kubeCluster)
|
||||
if err != nil {
|
||||
return nil, trace.Wrap(err)
|
||||
}
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
return resources, nil
|
||||
}
|
||||
default:
|
||||
}
|
||||
return types.ResourcesWithLabels{resource}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user