mirror of
https://github.com/replicatedhq/troubleshoot.git
synced 2026-04-15 07:16:34 +00:00
* fix remote host collection rbac checks * move saveNodeList into collectRemoteHost function * fix resource attribute list and retrieve namespace from kubeconfig * revert change to set a default namespace from kubeconfig * remove duplicate code
114 lines
2.5 KiB
Go
114 lines
2.5 KiB
Go
package supportbundle
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
"github.com/replicatedhq/troubleshoot/pkg/collect"
|
|
authorizationv1 "k8s.io/api/authorization/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/rest"
|
|
)
|
|
|
|
// Custom error type for RBAC permission errors
|
|
type RBACPermissionError struct {
|
|
Forbidden []error
|
|
}
|
|
|
|
func (e *RBACPermissionError) Error() string {
|
|
return fmt.Sprintf("insufficient permissions: %v", e.Forbidden)
|
|
}
|
|
|
|
func (e *RBACPermissionError) HasErrors() bool {
|
|
return len(e.Forbidden) > 0
|
|
}
|
|
|
|
// checkRBAC checks if the current user has the necessary permissions to run the collectors
|
|
func checkRemoteCollectorRBAC(ctx context.Context, clientConfig *rest.Config, title string, namespace string) error {
|
|
client, err := kubernetes.NewForConfig(clientConfig)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create client from config")
|
|
}
|
|
|
|
var forbidden []error
|
|
|
|
resourceAttributesList := []authorizationv1.ResourceAttributes{
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "get",
|
|
Resource: "pods",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "create",
|
|
Resource: "pods",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "delete",
|
|
Resource: "pods",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "get",
|
|
Resource: "pods/log",
|
|
},
|
|
{
|
|
Verb: "list",
|
|
Resource: "nodes",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "get",
|
|
Resource: "configmaps",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "create",
|
|
Resource: "configmaps",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "delete",
|
|
Resource: "configmaps",
|
|
},
|
|
{
|
|
Namespace: namespace,
|
|
Verb: "get",
|
|
Resource: "serviceaccounts",
|
|
},
|
|
}
|
|
|
|
for _, resourceAttributes := range resourceAttributesList {
|
|
spec := authorizationv1.SelfSubjectAccessReviewSpec{
|
|
ResourceAttributes: &resourceAttributes,
|
|
}
|
|
|
|
sar := &authorizationv1.SelfSubjectAccessReview{
|
|
Spec: spec,
|
|
}
|
|
|
|
resp, err := client.AuthorizationV1().SelfSubjectAccessReviews().Create(ctx, sar, metav1.CreateOptions{})
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to run subject review")
|
|
}
|
|
|
|
if !resp.Status.Allowed {
|
|
forbidden = append(forbidden, collect.RBACError{
|
|
DisplayName: title,
|
|
Namespace: spec.ResourceAttributes.Namespace,
|
|
Resource: spec.ResourceAttributes.Resource,
|
|
Verb: spec.ResourceAttributes.Verb,
|
|
})
|
|
}
|
|
}
|
|
|
|
if len(forbidden) > 0 {
|
|
return &RBACPermissionError{Forbidden: forbidden}
|
|
}
|
|
|
|
return nil
|
|
}
|