Fix resource kinds for search (#13142)

This commit is contained in:
Nic Klaassen
2022-06-06 18:34:08 +00:00
committed by GitHub
parent 9c046930ff
commit faae2f8a5c
3 changed files with 76 additions and 9 deletions
-4
View File
@@ -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,
}
+22 -3
View File
@@ -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
+54 -2
View File
@@ -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
}