zhangguanzhang's Blog

python kubernetes client list permission

字数统计: 1.2k阅读时长: 6 min
2022/03/24

由来

这几天内部有个功能就是看 kubernetes client 的权限有哪些

过程

kubeconfig 生成

先制作一个非 admin 的 kubeconfig,记得以前有个项目是部署后可以生成 kubeconfig 的,询问了一番后,其他群友提示下想起来是 permission-manager,部署后结果发现生成的 kubeconfig 压根不能用,报错未知机构签署的,结果还是按照以前 生成kubeconfig常规的两种方法 生成了一个简单的。

尝试过程

其实一开始打算自己写逻辑,增删改查需要的资源便利来检查,然后突然想起来 kubectl (忘了哪个版本开始)有个 auth 子命令的 can-i 来列出权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
$ kubectl --kubeconfig=/etc/kubernetes/develoop.kubeconfig  auth can-i --namespace xxx --list -v=8
I0325 15:58:24.972928 31603 loader.go:379] Config loaded from file: /etc/kubernetes/develoop.kubeconfig
I0325 15:58:24.974793 31603 request.go:1107] Request Body: {"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{"namespace":"xxx"},"status":{"resourceRules":null,"nonResourceRules":null,"incomplete":false}}
I0325 15:58:24.974912 31603 round_trippers.go:422] POST https://127.0.0.1:8443/apis/authorization.k8s.io/v1/selfsubjectrulesreviews
I0325 15:58:24.974927 31603 round_trippers.go:429] Request Headers:
I0325 15:58:24.974938 31603 round_trippers.go:433] Accept: application/json, */*
I0325 15:58:24.974947 31603 round_trippers.go:433] Content-Type: application/json
I0325 15:58:24.974957 31603 round_trippers.go:433] User-Agent: kubectl/v1.20.6 (linux/amd64) kubernetes/8a62859
I0325 15:58:24.974968 31603 round_trippers.go:433] Authorization: Bearer <masked>
I0325 15:58:25.007471 31603 round_trippers.go:448] Response Status: 201 Created in 32 milliseconds
I0325 15:58:25.007513 31603 round_trippers.go:451] Response Headers:
I0325 15:58:25.007523 31603 round_trippers.go:454] Cache-Control: no-cache, private
I0325 15:58:25.007530 31603 round_trippers.go:454] Content-Type: application/json
I0325 15:58:25.007537 31603 round_trippers.go:454] X-Kubernetes-Pf-Flowschema-Uid: 39e31546-1002-4e5b-a810-7bbeb09467a5
I0325 15:58:25.007547 31603 round_trippers.go:454] X-Kubernetes-Pf-Prioritylevel-Uid: 08ee1b31-c8de-4f8a-aa1c-b098f4e02ae1
I0325 15:58:25.007554 31603 round_trippers.go:454] Content-Length: 1028
I0325 15:58:25.007561 31603 round_trippers.go:454] Date: Fri, 25 Mar 2022 07:58:25 GMT
I0325 15:58:25.007656 31603 request.go:1107] Response Body: {"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","metadata":{"creationTimestamp":null},"spec":{},"status":{"resourceRules":[{"verbs":["create"],"apiGroups":["authorization.k8s.io"],"resources":["selfsubjectaccessreviews","selfsubjectrulesreviews"]},{"verbs":["*"],"apiGroups":["*"],"resources":["secrets","configmaps","serviceaccounts","endpoints","events","pods","pods/log","pods/portforward","podtemplates","resourcequotas","limitranges","services","replicationcontrollers","daemonsets","deployments","replicasets","statefulsets","cronjobs","jobs","persistentvolumeclaims","ingresses","networkpolicies","poddisruptionbudgets"]}],"nonResourceRules":[{"verbs":["get"],"nonResourceURLs":["/healthz","/livez","/readyz","/version","/version/"]},{"verbs":["get"],"nonResourceURLs":["/api","/api/*","/apis","/apis/*","/healthz","/livez","/openapi","/openapi/*","/readyz","/version","/version/"]},{"verbs":["get"],"nonResourceURLs":["/.well-known/openid-configuration","/openid/v1/jwks"]}],"incomplete":fals [truncated 4 chars]
Resources Non-Resource URLs Resource Names Verbs
configmaps.* [] [] [*]
cronjobs.* [] [] [*]
daemonsets.* [] [] [*]
deployments.* [] [] [*]
endpoints.* [] [] [*]
events.* [] [] [*]
ingresses.* [] [] [*]
jobs.* [] [] [*]
limitranges.* [] [] [*]
networkpolicies.* [] [] [*]
persistentvolumeclaims.* [] [] [*]
poddisruptionbudgets.* [] [] [*]
pods.*/log [] [] [*]
pods.*/portforward [] [] [*]
pods.* [] [] [*]
podtemplates.* [] [] [*]
replicasets.* [] [] [*]
replicationcontrollers.* [] [] [*]
resourcequotas.* [] [] [*]
secrets.* [] [] [*]
serviceaccounts.* [] [] [*]
services.* [] [] [*]
statefulsets.* [] [] [*]
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
[/.well-known/openid-configuration] [] [get]
[/api/*] [] [get]
[/api] [] [get]
[/apis/*] [] [get]
[/apis] [] [get]
[/healthz] [] [get]
[/healthz] [] [get]
[/livez] [] [get]
[/livez] [] [get]
[/openapi/*] [] [get]
[/openapi] [] [get]
[/openid/v1/jwks] [] [get]
[/readyz] [] [get]
[/readyz] [] [get]
[/version/] [] [get]
[/version/] [] [get]
[/version] [] [get]
[/version] [] [get]

搜索 python kubernetes client selfsubjectrulesreviews 搜到官方的 create_self_subject_rules_review 示例

试了下报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ cat t2

from kubernetes import client, config

if __name__ == "__main__":
body = client.V1SelfSubjectRulesReview()
print(body)
$ python t2
Traceback (most recent call last):
File "t2", line 5, in <module>
body = client.V1SelfSubjectRulesReview()
File "/usr/local/lib/python3.7/site-packages/kubernetes/client/models/v1_self_subject_rules_review.py", line 70, in __init__
self.spec = spec
File "/usr/local/lib/python3.7/site-packages/kubernetes/client/models/v1_self_subject_rules_review.py", line 160, in spec
raise ValueError("Invalid value for `spec`, must not be `None`") # noqa: E501
ValueError: Invalid value for `spec`, must not be `None`

大概看了下这个类 V1SelfSubjectRulesReview,需要传递 spec 属性才不会报错,点击跳转到模块源码里,没看到啥有用的参考,毕竟弱语言类型。后面找了个 V1SelfSubjectRulesReviewSpec,单独传个空的 v1 spec 就会报错缺少 namespace,按照 python 的 client 库习惯,尝试了下面的还是报错:

1
2
rule_review_spec = client.V1SelfSubjectAccessReviewSpec(namespace='xxx')
body = c.V1SelfSubjectRulesReview(spec=rule_review_spec)

最后摸索出来下面这样才对,真是无语了:

1
2
3
body = client.V1SelfSubjectRulesReview(spec={"namespace": namespace})
result = client.AuthorizationV1Api().create_self_subject_rules_review(body=body)
return result.status.resource_rules

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[{'api_groups': ['authorization.k8s.io'],
'resource_names': None,
'resources': ['selfsubjectaccessreviews', 'selfsubjectrulesreviews'],
'verbs': ['create']}, {'api_groups': ['*'],
'resource_names': None,
'resources': ['secrets',
'configmaps',
'serviceaccounts',
'endpoints',
'events',
'pods',
'pods/log',
'pods/portforward',
'podtemplates',
'resourcequotas',
'limitranges',
'services',
'replicationcontrollers',
'daemonsets',
'deployments',
'replicasets',
'statefulsets',
'cronjobs',
'jobs',
'persistentvolumeclaims',
'ingresses',
'networkpolicies',
'poddisruptionbudgets'],
'verbs': ['*']}]

参考

CATALOG
  1. 1. 由来
  2. 2. 过程
    1. 2.1. kubeconfig 生成
    2. 2.2. 尝试过程
  3. 3. 参考