如何使用 kubernetes go-client 进行模拟工作

问题描述

我正在寻找一种使用 kubernetes go-client 运行 kubectl auth can-i get pods --as system:serviceaccount:default:test 的方法。

到目前为止,我得到了以下代码,但它不起作用,因为与 kubectl auth can-i 相比,我得到了不同的响应。我知道这是关于模拟的,所以我添加了 rest.ImpersonationConfig 但它仍然不起作用。

重现步骤:

kind create cluster
kubectl create sa test
kubectl create role test --verb=get --verb=list --resource=pods
kubectl create rolebinding test --role=test --serviceaccount=default:test

kubectl auth can-i get pod --as system:serviceaccount:default:test
# yes

代码:

package main

import (
    "context"
    "fmt"
    "os"

    authv1 "k8s.io/api/authorization/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {

    kubeconfig := fmt.Sprintf("%s/.kube/config",os.Getenv("HOME"))
    config,err := clientcmd.BuildConfigFromFlags("",kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    config.Impersonate = rest.ImpersonationConfig{
        UserName: "system:serviceaccount:default:test",}

    clientset,err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    action := authv1.ResourceAttributes{
        Namespace: "default",Verb:      "get",Resource:  "pod",}

    selfCheck := authv1.SelfSubjectAccessReview{
        Spec: authv1.SelfSubjectAccessReviewSpec{
            ResourceAttributes: &action,},}

    resp,err := clientset.AuthorizationV1().
        SelfSubjectAccessReviews().
        Create(context.TODO(),&selfCheck,metav1.CreateOptions{})

    if err != nil {
        panic(err.Error())
    }

    if resp.Status.Allowed {
        fmt.Println("allowed")
    } else {
        fmt.Println("denied")
    }
}

解决方法

我想通了!我在 ResourceAttributes 中使用了单数形式的“pod”而不是复数形式的“pods”。

package main

import (
    "context"
    "fmt"
    "os"

    authv1 "k8s.io/api/authorization/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
)

func main() {

    kubeconfig := fmt.Sprintf("%s/.kube/config",os.Getenv("HOME"))
    config,err := clientcmd.BuildConfigFromFlags("",kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    config.Impersonate = rest.ImpersonationConfig{
        UserName: "system:serviceaccount:default:test",}

    clientset,err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    action := authv1.ResourceAttributes{
        Namespace: "default",Verb:      "get",Resource:  "pods",}

    selfCheck := authv1.SelfSubjectAccessReview{
        Spec: authv1.SelfSubjectAccessReviewSpec{
            ResourceAttributes: &action,},}

    resp,err := clientset.AuthorizationV1().
        SelfSubjectAccessReviews().
        Create(context.TODO(),&selfCheck,metav1.CreateOptions{})

    if err != nil {
        panic(err.Error())
    }

    if resp.Status.Allowed {
        fmt.Println("allowed")
    } else {
        fmt.Println("denied")
    }
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...