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 }