mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-05-02 05:46:22 +00:00
* Remove `logger` module * Remove `shared` module * Move `cli` folder contents into project root * Fix linter * Change the module name from `github.com/kubeshark/kubeshark/cli` to `github.com/kubeshark/kubeshark` * Set the default `Makefile` rule to `build` * Add `lint` rule * Fix the linter errors
133 lines
4.8 KiB
Go
133 lines
4.8 KiB
Go
package check
|
|
|
|
import (
|
|
"context"
|
|
"embed"
|
|
"fmt"
|
|
"log"
|
|
"strings"
|
|
|
|
"github.com/kubeshark/kubeshark/bucket"
|
|
"github.com/kubeshark/kubeshark/config"
|
|
"github.com/kubeshark/kubeshark/kubernetes"
|
|
"github.com/kubeshark/kubeshark/uiUtils"
|
|
rbac "k8s.io/api/rbac/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/client-go/kubernetes/scheme"
|
|
)
|
|
|
|
func TapKubernetesPermissions(ctx context.Context, embedFS embed.FS, kubernetesProvider *kubernetes.Provider) bool {
|
|
log.Printf("\nkubernetes-permissions\n--------------------")
|
|
|
|
var filePath string
|
|
if config.Config.IsNsRestrictedMode() {
|
|
filePath = "permissionFiles/permissions-ns-tap.yaml"
|
|
} else {
|
|
filePath = "permissionFiles/permissions-all-namespaces-tap.yaml"
|
|
}
|
|
|
|
data, err := embedFS.ReadFile(filePath)
|
|
if err != nil {
|
|
log.Printf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
|
return false
|
|
}
|
|
|
|
decode := scheme.Codecs.UniversalDeserializer().Decode
|
|
obj, _, err := decode(data, nil, nil)
|
|
if err != nil {
|
|
log.Printf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
|
return false
|
|
}
|
|
|
|
switch resource := obj.(type) {
|
|
case *rbac.Role:
|
|
return checkRulesPermissions(ctx, kubernetesProvider, resource.Rules, config.Config.KubesharkResourcesNamespace)
|
|
case *rbac.ClusterRole:
|
|
return checkRulesPermissions(ctx, kubernetesProvider, resource.Rules, "")
|
|
}
|
|
|
|
log.Printf("%v error while checking kubernetes permissions, err: resource of type 'Role' or 'ClusterRole' not found in permission files", fmt.Sprintf(uiUtils.Red, "✗"))
|
|
return false
|
|
}
|
|
|
|
func InstallKubernetesPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
|
log.Printf("\nkubernetes-permissions\n--------------------")
|
|
|
|
bucketProvider := bucket.NewProvider(config.Config.Install.TemplateUrl, bucket.DefaultTimeout)
|
|
installTemplate, err := bucketProvider.GetInstallTemplate(config.Config.Install.TemplateName)
|
|
if err != nil {
|
|
log.Printf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
|
return false
|
|
}
|
|
|
|
resourcesTemplate := strings.Split(installTemplate, "---")[1:]
|
|
|
|
permissionsExist := true
|
|
|
|
decode := scheme.Codecs.UniversalDeserializer().Decode
|
|
for _, resourceTemplate := range resourcesTemplate {
|
|
obj, _, err := decode([]byte(resourceTemplate), nil, nil)
|
|
if err != nil {
|
|
log.Printf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
|
return false
|
|
}
|
|
|
|
groupVersionKind := obj.GetObjectKind().GroupVersionKind()
|
|
resource := fmt.Sprintf("%vs", strings.ToLower(groupVersionKind.Kind))
|
|
permissionsExist = checkCreatePermission(ctx, kubernetesProvider, resource, groupVersionKind.Group, obj.(metav1.Object).GetNamespace()) && permissionsExist
|
|
|
|
switch resourceObj := obj.(type) {
|
|
case *rbac.Role:
|
|
permissionsExist = checkRulesPermissions(ctx, kubernetesProvider, resourceObj.Rules, resourceObj.Namespace) && permissionsExist
|
|
case *rbac.ClusterRole:
|
|
permissionsExist = checkRulesPermissions(ctx, kubernetesProvider, resourceObj.Rules, "") && permissionsExist
|
|
}
|
|
}
|
|
|
|
return permissionsExist
|
|
}
|
|
|
|
func checkCreatePermission(ctx context.Context, kubernetesProvider *kubernetes.Provider, resource string, group string, namespace string) bool {
|
|
exist, err := kubernetesProvider.CanI(ctx, namespace, resource, "create", group)
|
|
return checkPermissionExist(group, resource, "create", namespace, exist, err)
|
|
}
|
|
|
|
func checkRulesPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider, rules []rbac.PolicyRule, namespace string) bool {
|
|
permissionsExist := true
|
|
|
|
for _, rule := range rules {
|
|
for _, group := range rule.APIGroups {
|
|
for _, resource := range rule.Resources {
|
|
for _, verb := range rule.Verbs {
|
|
exist, err := kubernetesProvider.CanI(ctx, namespace, resource, verb, group)
|
|
permissionsExist = checkPermissionExist(group, resource, verb, namespace, exist, err) && permissionsExist
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return permissionsExist
|
|
}
|
|
|
|
func checkPermissionExist(group string, resource string, verb string, namespace string, exist bool, err error) bool {
|
|
var groupAndNamespace string
|
|
if group != "" && namespace != "" {
|
|
groupAndNamespace = fmt.Sprintf("in api group '%v' and namespace '%v'", group, namespace)
|
|
} else if group != "" {
|
|
groupAndNamespace = fmt.Sprintf("in api group '%v'", group)
|
|
} else if namespace != "" {
|
|
groupAndNamespace = fmt.Sprintf("in namespace '%v'", namespace)
|
|
}
|
|
|
|
if err != nil {
|
|
log.Printf("%v error checking permission for %v %v %v, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, groupAndNamespace, err)
|
|
return false
|
|
} else if !exist {
|
|
log.Printf("%v can't %v %v %v", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, groupAndNamespace)
|
|
return false
|
|
}
|
|
|
|
log.Printf("%v can %v %v %v", fmt.Sprintf(uiUtils.Green, "√"), verb, resource, groupAndNamespace)
|
|
return true
|
|
}
|