Skip to content

Commit

Permalink
get cluster-resources even if negotiating RBAC fails (#1243)
Browse files Browse the repository at this point in the history
* log errors negotiating and set ignoreRBAC when authorizer webhooks would fail
  • Loading branch information
adamancini committed Jun 27, 2023
1 parent 2c6b186 commit 58c4283
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
19 changes: 19 additions & 0 deletions pkg/collect/cluster_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"

"github.com/replicatedhq/troubleshoot/pkg/k8sutil/discovery"
Expand Down Expand Up @@ -100,6 +101,7 @@ EMPTY_NAMESPACE_FOUND:
}

func (c *CollectClusterResources) Collect(progressChan chan<- interface{}) (CollectorResult, error) {
klog.V(4).Infof("CollectClusterResources.Collect")
client, err := kubernetes.NewForConfig(c.ClientConfig)
if err != nil {
return nil, err
Expand All @@ -118,16 +120,19 @@ func (c *CollectClusterResources) Collect(progressChan chan<- interface{}) (Coll
var namespaceNames []string
if len(c.Collector.Namespaces) > 0 {
namespaces, namespaceErrors := getNamespaces(ctx, client, c.Collector.Namespaces)
klog.V(4).Infof("checking for namespaces access: %s", string(namespaces))
namespaceNames = c.Collector.Namespaces
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NAMESPACES)), bytes.NewBuffer(namespaces))
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s-errors.json", constants.CLUSTER_RESOURCES_NAMESPACES)), marshalErrors(namespaceErrors))
} else if c.Namespace != "" {
namespace, namespaceErrors := getNamespace(ctx, client, c.Namespace)
klog.V(4).Infof("checking for namespace access: %s", string(namespace))
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NAMESPACES)), bytes.NewBuffer(namespace))
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s-errors.json", constants.CLUSTER_RESOURCES_NAMESPACES)), marshalErrors(namespaceErrors))
namespaceNames = append(namespaceNames, c.Namespace)
} else {
namespaces, namespaceList, namespaceErrors := getAllNamespaces(ctx, client)
klog.V(4).Infof("checking for all namespaces access: %s", string(namespaces))
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s.json", constants.CLUSTER_RESOURCES_NAMESPACES)), bytes.NewBuffer(namespaces))
output.SaveResult(c.BundlePath, path.Join(constants.CLUSTER_RESOURCES_DIR, fmt.Sprintf("%s-errors.json", constants.CLUSTER_RESOURCES_NAMESPACES)), marshalErrors(namespaceErrors))
if namespaceList != nil {
Expand Down Expand Up @@ -156,6 +161,7 @@ func (c *CollectClusterResources) Collect(progressChan chan<- interface{}) (Coll
}
}
namespaceNames = filteredNamespaces
klog.V(4).Infof("filtered to namespaceNames %s", namespaceNames)
}

// pods
Expand Down Expand Up @@ -1598,6 +1604,10 @@ func getSelfSubjectRulesReviews(ctx context.Context, client *kubernetes.Clientse
continue
}

if response.Status.Incomplete == true {
errorsByNamespace[namespace] = response.Status.EvaluationError
}

statusByNamespace[namespace] = response.Status.DeepCopy()
}

Expand Down Expand Up @@ -1661,13 +1671,20 @@ func events(ctx context.Context, client *kubernetes.Clientset, namespaces []stri
func canCollectNamespaceResources(status *authorizationv1.SubjectRulesReviewStatus) bool {
// This is all very approximate

if status.Incomplete && (status.EvaluationError == constants.SELFSUBJECTRULESREVIEW_ERROR_AUTHORIZATION_WEBHOOK_UNSUPPORTED) {
klog.V(4).Infof("could not negotiate RBAC because of an unsupported authorizer webhook; try to get resources from this namespace anyway.")
return true
}

klog.V(4).Infof("canCollectNamespaceResources: %+v", status)
for _, resource := range status.ResourceRules {
hasGet := false
for _, verb := range resource.Verbs {
if verb == "*" || verb == "get" {
hasGet = true
break
}
klog.V(4).Infof("resource: %+v hasGet: %t", resource, hasGet)
}

hasAPI := false
Expand All @@ -1676,6 +1693,7 @@ func canCollectNamespaceResources(status *authorizationv1.SubjectRulesReviewStat
hasAPI = true
break
}
klog.V(4).Infof("group: %+v hasGet: %t", group, hasAPI)
}

hasPods := false
Expand All @@ -1684,6 +1702,7 @@ func canCollectNamespaceResources(status *authorizationv1.SubjectRulesReviewStat
hasPods = true
break
}
klog.V(4).Infof("resource: %+v hasPods: %t", resource, hasPods)
}

if hasGet && hasAPI && hasPods {
Expand Down
3 changes: 3 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ const (
CLUSTER_RESOURCES_PRIORITY_CLASS = "priorityclasses"
CLUSTER_RESOURCES_ENDPOINTS = "endpoints"

// SelfSubjectRulesReview evaluation responses
SELFSUBJECTRULESREVIEW_ERROR_AUTHORIZATION_WEBHOOK_UNSUPPORTED = "webhook authorizer does not support user rule resolution"

// Custom exit codes
EXIT_CODE_CATCH_ALL = 1
EXIT_CODE_SPEC_ISSUES = 2
Expand Down

0 comments on commit 58c4283

Please sign in to comment.