From 030e2484220cd353fa2026b808f5ff0ee1094876 Mon Sep 17 00:00:00 2001 From: Andrew Suderman Date: Fri, 23 Oct 2020 09:46:10 -0600 Subject: [PATCH] Fix logic with service accounts. Update e2e tests. Add test coverage (#141) * Write tests to prove that #42 is a bug * Fix logic with subject key * add more test coverage * more e2e tests to cover bugs * udpate kind and kube images for e2e tests --- .circleci/config.yml | 21 +- .gitignore | 1 + e2e/test.sh | 3 +- e2e/tests/00_assets/0_namespaces.yaml | 32 ++++ e2e/tests/00_assets/1_serviceaccounts.yaml | 12 ++ e2e/tests/00_assets/2_bindings.yaml | 54 ++++++ e2e/tests/00_assets/clusterrolebinding.yaml | 12 -- e2e/tests/00_assets/serviceaccount.yaml | 5 - e2e/tests/00_test.yaml | 10 +- go.sum | 27 +++ lookup/lister.go | 22 ++- lookup/lister_test.go | 201 ++++++++++++++++---- lookup/rbac_subject.go | 7 +- 13 files changed, 322 insertions(+), 85 deletions(-) create mode 100644 e2e/tests/00_assets/0_namespaces.yaml create mode 100644 e2e/tests/00_assets/1_serviceaccounts.yaml create mode 100644 e2e/tests/00_assets/2_bindings.yaml delete mode 100644 e2e/tests/00_assets/clusterrolebinding.yaml delete mode 100644 e2e/tests/00_assets/serviceaccount.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml index b03919d..fb7722c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,6 +22,7 @@ references: executor: golang-exec pre_script: e2e/pre.sh store-test-results: /tmp/test-results + kind_version: 0.9.0 script: e2e/test.sh requires: - test @@ -66,24 +67,20 @@ workflows: branches: only: /.*/ - rok8s-scripts/kubernetes_e2e_tests: - name: e2e test kube 1.15.7 - kind_node_image: >- - "kindest/node:v1.15.7@sha256:e2df133f80ef633c53c0200114fce2ed5e1f6947477dbc83261a6a921169488d" + name: e2e test kube 1.16 + kind_node_image: "kindest/node:v1.16.15@sha256:a89c771f7de234e6547d43695c7ab047809ffc71a0c3b65aa54eda051c45ed20" <<: *e2e_config - rok8s-scripts/kubernetes_e2e_tests: - name: e2e test kube 1.16.4 - kind_node_image: >- - "kindest/node:v1.16.4@sha256:b91a2c2317a000f3a783489dfb755064177dbc3a0b2f4147d50f04825d016f55" + name: e2e test kube 1.17 + kind_node_image: "kindest/node:v1.17.11@sha256:5240a7a2c34bf241afb54ac05669f8a46661912eab05705d660971eeb12f6555" <<: *e2e_config - rok8s-scripts/kubernetes_e2e_tests: - name: e2e test kube 1.17.0 - kind_node_image: >- - "kindest/node:v1.17.0@sha256:9512edae126da271b66b990b6fff768fbb7cd786c7d39e86bdf55906352fdf62" + name: e2e test kube 1.18 + kind_node_image: "kindest/node:v1.18.8@sha256:f4bcc97a0ad6e7abaf3f643d890add7efe6ee4ab90baeb374b4f41a4c95567eb" <<: *e2e_config - rok8s-scripts/kubernetes_e2e_tests: - name: e2e test kube 1.18.0 - kind_node_image: >- - "kindest/node:v1.18.0@sha256:0e20578828edd939d25eb98496a685c76c98d54084932f76069f886ec315d694" + name: e2e test kube 1.19 + kind_node_image: "kindest/node:v1.19.1@sha256:98cf5288864662e37115e362b23e4369c8c4a408f99cbc06e58ac30ddc721600" <<: *e2e_config - release: filters: diff --git a/.gitignore b/.gitignore index 7283bfe..bba1f80 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ coverage.txt cover.html /rbac-lookup +/e2e/tests/rbac-lookup diff --git a/e2e/test.sh b/e2e/test.sh index b7283ba..edfceac 100644 --- a/e2e/test.sh +++ b/e2e/test.sh @@ -13,8 +13,9 @@ curl -LO https://github.com/ovh/venom/releases/download/v0.27.0/venom.linux-amd6 mv venom.linux-amd64 /usr/local/bin/venom chmod +x /usr/local/bin/venom +mv /rbac-lookup/rbac-lookup /rbac-lookup/e2e/tests + cd /rbac-lookup/e2e mkdir -p /tmp/test-results venom run tests/* --log debug --output-dir=/tmp/test-results --strict exit $? - diff --git a/e2e/tests/00_assets/0_namespaces.yaml b/e2e/tests/00_assets/0_namespaces.yaml new file mode 100644 index 0000000..8a378b7 --- /dev/null +++ b/e2e/tests/00_assets/0_namespaces.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: one +spec: + finalizers: + - kubernetes +--- +apiVersion: v1 +kind: Namespace +metadata: + name: two +spec: + finalizers: + - kubernetes +--- +apiVersion: v1 +kind: Namespace +metadata: + name: three +spec: + finalizers: + - kubernetes +--- +apiVersion: v1 +kind: Namespace +metadata: + name: circleci +spec: + finalizers: + - kubernetes diff --git a/e2e/tests/00_assets/1_serviceaccounts.yaml b/e2e/tests/00_assets/1_serviceaccounts.yaml new file mode 100644 index 0000000..30081fb --- /dev/null +++ b/e2e/tests/00_assets/1_serviceaccounts.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: e2e-test + namespace: default +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: circleci + namespace: circleci diff --git a/e2e/tests/00_assets/2_bindings.yaml b/e2e/tests/00_assets/2_bindings.yaml new file mode 100644 index 0000000..4999917 --- /dev/null +++ b/e2e/tests/00_assets/2_bindings.yaml @@ -0,0 +1,54 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: e2e-test-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: e2e-test + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: circleci-cluster-admin +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: circleci + namespace: circleci +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: circleci-cluster-admin + namespace: one +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: circleci + namespace: circleci +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: circleci-cluster-admin + namespace: two +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: +- kind: ServiceAccount + name: circleci + namespace: circleci diff --git a/e2e/tests/00_assets/clusterrolebinding.yaml b/e2e/tests/00_assets/clusterrolebinding.yaml deleted file mode 100644 index 8db4eb5..0000000 --- a/e2e/tests/00_assets/clusterrolebinding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: e2e-test-binding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: cluster-admin -subjects: -- kind: ServiceAccount - name: e2e-test - namespace: default diff --git a/e2e/tests/00_assets/serviceaccount.yaml b/e2e/tests/00_assets/serviceaccount.yaml deleted file mode 100644 index f785c03..0000000 --- a/e2e/tests/00_assets/serviceaccount.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: e2e-test - namespace: default diff --git a/e2e/tests/00_test.yaml b/e2e/tests/00_test.yaml index c4e179b..855a803 100644 --- a/e2e/tests/00_test.yaml +++ b/e2e/tests/00_test.yaml @@ -9,10 +9,18 @@ testcases: - script: kubectl apply -f 00_assets/ - name: Rbac Lookup steps: - - script: /rbac-lookup/rbac-lookup e2e-test + - script: ./rbac-lookup e2e-test assertions: - result.code ShouldEqual 0 - result.systemerr ShouldNotEqual "No RBAC Bindings found" +- name: rbac lookup circleci + steps: + - script: ./rbac-lookup circleci -owide + assertions: + - result.code ShouldEqual 0 + - result.systemout ShouldContainSubstring "ServiceAccount/circleci:circleci two ClusterRole/cluster-admin RoleBinding/circleci-cluster-admin" + - result.systemout ShouldContainSubstring "ServiceAccount/circleci:circleci cluster-wide ClusterRole/cluster-admin ClusterRoleBinding/circleci-cluster-admin" + - result.systemout ShouldContainSubstring "ServiceAccount/circleci:circleci one ClusterRole/cluster-admin RoleBinding/circleci-cluster-admin" - name: Cleanup steps: - script: kubectl delete -f 00_assets/ diff --git a/go.sum b/go.sum index 3591a59..7fc8273 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,7 @@ cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -36,12 +37,15 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0= @@ -93,6 +97,7 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -106,6 +111,7 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= @@ -147,6 +153,7 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -182,6 +189,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1 github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0 h1:rVsPeBmXbYv4If/cumu1AzZPwV58q433hvONV1UEZoI= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.4.1 h1:DLJCy1n/vrD4HPjOvYcT8aYQXpPIzoRZONaYwyycI+I= github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= @@ -206,6 +214,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -247,6 +256,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -304,6 +314,7 @@ go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -317,6 +328,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -385,6 +397,7 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -393,6 +406,7 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -439,6 +453,7 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f h1:Fqb3ao1hUmOR3GkUOg/Y+BadLwykBIzs5q8Ez2SbHyc= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -446,6 +461,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= @@ -532,6 +548,7 @@ google.golang.org/api v0.31.0 h1:1w5Sz/puhxFo9lTtip2n47k7toB/U2nCqOKNHd3Yrbo= google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= google.golang.org/api v0.32.0 h1:Le77IccnTqEa8ryp9wIpX5W3zYm7Gf9LhOp9PHcwFts= google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.33.0 h1:+gL0XvACeMIvpwLZ5rQZzLn5cwOsgg8dIcfJ2SYfBVw= google.golang.org/api v0.33.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -574,6 +591,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d h1:92D1fum1bJLKSdr11OJ+54YeCMCGYIygTA7R/YZxH5M= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -591,6 +609,7 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -601,6 +620,7 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -641,6 +661,7 @@ k8s.io/api v0.19.0/go.mod h1:I1K45XlvTrDjmj5LoM5LuP/KYrhWbjUKT/SoPG0qTjw= k8s.io/api v0.19.1 h1:oZf4bYsBdjC49PdTwNfLmrfUFCwKUi94HY/+emXI8Qw= k8s.io/api v0.19.1/go.mod h1:+u/k4/K/7vp4vsfdT7dyl8Oxk1F26Md4g5F26Tu85PU= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= +k8s.io/api v0.19.3 h1:GN6ntFnv44Vptj/b+OnMW7FmzkpDoIDLZRvKX3XH9aU= k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= k8s.io/apimachinery v0.18.4 h1:ST2beySjhqwJoIFk6p7Hp5v5O0hYY6Gngq/gUYXTPIA= k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= @@ -651,6 +672,7 @@ k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMi k8s.io/apimachinery v0.19.0/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.19.1/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= +k8s.io/apimachinery v0.19.3 h1:bpIQXlKjB4cB/oNpnNnV+BybGPR7iP5oYpsOTEJ4hgc= k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/client-go v0.18.4 h1:un55V1Q/B3JO3A76eS0kUSywgGK/WR3BQ8fHQjNa6Zc= k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= @@ -664,6 +686,7 @@ k8s.io/client-go v0.19.1 h1:xfFwj+YFKa8rcihlFYZABjxcy7Sm/wJQ+GxW3JyVtKI= k8s.io/client-go v0.19.1/go.mod h1:AZOIVSI9UUtQPeJD3zJFp15CEhSjRgAuQP5PWRJrCIQ= k8s.io/client-go v0.19.2 h1:gMJuU3xJZs86L1oQ99R4EViAADUPMHHtS9jFshasHSc= k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= +k8s.io/client-go v0.19.3 h1:ctqR1nQ52NUs6LpI0w+a5U+xjYwflFwA13OJKcicMxg= k8s.io/client-go v0.19.3/go.mod h1:+eEMktZM+MG0KO+PTkci8xnbCZHvj9TqR6Q1XDUIJOM= k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= @@ -673,12 +696,15 @@ k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0 h1:XRvcwJozkgZ1UQJmfMGpvRthQHOvihEhYtDfAaxMz/A= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY= k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6 h1:+WnxoVtG8TMiudHBSEtrVL1egv36TkkJm+bA8AxicmQ= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200729134348-d5654de09c73 h1:uJmqzgNWG7XyClnU/mLPBWwfKKF1K8Hf8whTseBgJcg= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= @@ -686,6 +712,7 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/lookup/lister.go b/lookup/lister.go index 3a16c4b..6e0b48d 100644 --- a/lookup/lister.go +++ b/lookup/lister.go @@ -113,7 +113,11 @@ func (l *lister) loadRoleBindings() error { for _, roleBinding := range roleBindings.Items { for _, subject := range roleBinding.Subjects { if l.nameMatches(subject.Name) && l.kindMatches(subject.Kind) { - if rbacSubj, exist := l.rbacSubjectsByScope[subject.Name]; exist { + subjectKey := subject.Name + if subject.Kind == "ServiceAccount" { + subjectKey = fmt.Sprintf("%s:%s", subject.Namespace, subject.Name) + } + if rbacSubj, exist := l.rbacSubjectsByScope[subjectKey]; exist { rbacSubj.addRoleBinding(&roleBinding) } else { rbacSubj := rbacSubject{ @@ -121,10 +125,7 @@ func (l *lister) loadRoleBindings() error { RolesByScope: make(map[string][]simpleRole), } rbacSubj.addRoleBinding(&roleBinding) - subjectKey := subject.Name - if rbacSubj.Kind == "ServiceAccount" { - subjectKey = fmt.Sprintf("%s:%s", subject.Namespace, subject.Name) - } + l.rbacSubjectsByScope[subjectKey] = rbacSubj } } @@ -145,7 +146,11 @@ func (l *lister) loadClusterRoleBindings() error { for _, clusterRoleBinding := range clusterRoleBindings.Items { for _, subject := range clusterRoleBinding.Subjects { if l.nameMatches(subject.Name) && l.kindMatches(subject.Kind) { - if rbacSubj, exist := l.rbacSubjectsByScope[subject.Name]; exist { + subjectKey := subject.Name + if subject.Kind == "ServiceAccount" { + subjectKey = fmt.Sprintf("%s:%s", subject.Namespace, subject.Name) + } + if rbacSubj, exist := l.rbacSubjectsByScope[subjectKey]; exist { rbacSubj.addClusterRoleBinding(&clusterRoleBinding) } else { rbacSubj := rbacSubject{ @@ -153,10 +158,7 @@ func (l *lister) loadClusterRoleBindings() error { RolesByScope: make(map[string][]simpleRole), } rbacSubj.addClusterRoleBinding(&clusterRoleBinding) - subjectKey := subject.Name - if rbacSubj.Kind == "ServiceAccount" { - subjectKey = fmt.Sprintf("%s:%s", subject.Namespace, subject.Name) - } + l.rbacSubjectsByScope[subjectKey] = rbacSubj } } diff --git a/lookup/lister_test.go b/lookup/lister_test.go index 2909e42..7b6ce11 100644 --- a/lookup/lister_test.go +++ b/lookup/lister_test.go @@ -39,7 +39,7 @@ func TestLoadRoleBindings(t *testing.T) { loadRoleBindings(t, l) - assert.Len(t, l.rbacSubjectsByScope, 2, "Expected 2 rbac subjects") + assert.Len(t, l.rbacSubjectsByScope, 3, "Expected 3 rbac subjects") expectedRbacSubject := rbacSubject{ Kind: "User", @@ -55,8 +55,31 @@ func TestLoadRoleBindings(t *testing.T) { }, } - assert.EqualValues(t, l.rbacSubjectsByScope["joe"], expectedRbacSubject) - assert.EqualValues(t, l.rbacSubjectsByScope["sue"], expectedRbacSubject) + expectedRbacSubjectSA := rbacSubject{ + Kind: "ServiceAccount", + RolesByScope: map[string][]simpleRole{ + "two": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "RoleBinding", + Name: "testing-sa", + }, + }}, + "three": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "RoleBinding", + Name: "testing-sa", + }, + }}, + }, + } + + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["joe"]) + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["sue"]) + assert.EqualValues(t, expectedRbacSubjectSA, l.rbacSubjectsByScope["circleci:circleci"]) } func TestLoadClusterRoleBindings(t *testing.T) { @@ -70,7 +93,7 @@ func TestLoadClusterRoleBindings(t *testing.T) { loadClusterRoleBindings(t, l) - assert.Len(t, l.rbacSubjectsByScope, 2, "Expected 2 rbac subjects") + assert.Len(t, l.rbacSubjectsByScope, 3, "Expected 3 rbac subjects") expectedRbacSubject := rbacSubject{ Kind: "User", @@ -86,8 +109,23 @@ func TestLoadClusterRoleBindings(t *testing.T) { }, } - assert.EqualValues(t, l.rbacSubjectsByScope["joe"], expectedRbacSubject) - assert.EqualValues(t, l.rbacSubjectsByScope["sue"], expectedRbacSubject) + expectedRbacSubjectSA := rbacSubject{ + Kind: "ServiceAccount", + RolesByScope: map[string][]simpleRole{ + "cluster-wide": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "ClusterRoleBinding", + Name: "circleci-cluster-admin", + }, + }}, + }, + } + + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["joe"]) + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["sue"]) + assert.EqualValues(t, expectedRbacSubjectSA, l.rbacSubjectsByScope["circleci:circleci"]) } func TestLoadAll(t *testing.T) { @@ -103,7 +141,7 @@ func TestLoadAll(t *testing.T) { loadAll(t, l) - assert.Len(t, l.rbacSubjectsByScope, 2, "Expected 2 rbac subjects") + assert.Len(t, l.rbacSubjectsByScope, 3, "Expected 3 rbac subjects") expectedRbacSubject := rbacSubject{ Kind: "User", @@ -127,8 +165,39 @@ func TestLoadAll(t *testing.T) { }, } - assert.EqualValues(t, l.rbacSubjectsByScope["joe"], expectedRbacSubject) - assert.EqualValues(t, l.rbacSubjectsByScope["sue"], expectedRbacSubject) + expectedRbacSubjectSA := rbacSubject{ + Kind: "ServiceAccount", + RolesByScope: map[string][]simpleRole{ + "cluster-wide": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "ClusterRoleBinding", + Name: "circleci-cluster-admin", + }, + }}, + "two": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "RoleBinding", + Name: "testing-sa", + }, + }}, + "three": {{ + Kind: "ClusterRole", + Name: "cluster-admin", + Source: simpleRoleSource{ + Kind: "RoleBinding", + Name: "testing-sa", + }, + }}, + }, + } + + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["joe"]) + assert.EqualValues(t, expectedRbacSubject, l.rbacSubjectsByScope["sue"]) + assert.EqualValues(t, expectedRbacSubjectSA, l.rbacSubjectsByScope["circleci:circleci"]) } func TestLoadGke(t *testing.T) { @@ -247,7 +316,7 @@ func TestLoadGkeFilters(t *testing.T) { assert.Len(t, l.rbacSubjectsByScope, 2, "Expected 2 rbac subjects") - assert.EqualValues(t, l.rbacSubjectsByScope["jane@example.com"], rbacSubject{ + assert.EqualValues(t, rbacSubject{ Kind: "User", RolesByScope: map[string][]simpleRole{ "project-wide": {{ @@ -266,9 +335,9 @@ func TestLoadGkeFilters(t *testing.T) { }, }}, }, - }) + }, l.rbacSubjectsByScope["jane@example.com"]) - assert.EqualValues(t, l.rbacSubjectsByScope["joe@example.com"], rbacSubject{ + assert.EqualValues(t, rbacSubject{ Kind: "User", RolesByScope: map[string][]simpleRole{ "project-wide": {{ @@ -280,7 +349,7 @@ func TestLoadGkeFilters(t *testing.T) { }, }}, }, - }) + }, l.rbacSubjectsByScope["joe@example.com"]) } func genLister() lister { @@ -303,23 +372,55 @@ func loadRoleBindings(t *testing.T, l lister) { } func createRoleBindings(t *testing.T, l lister) { - roleBindings := []rbacv1.RoleBinding{{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testing", - Namespace: "foo", + roleBindings := []rbacv1.RoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "testing", + Namespace: "foo", + }, + Subjects: []rbacv1.Subject{{ + Name: "joe", + Kind: "User", + }, { + Name: "sue", + Kind: "User", + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "Role", + Name: "bar", + }, }, - Subjects: []rbacv1.Subject{{ - Name: "joe", - Kind: "User", - }, { - Name: "sue", - Kind: "User", - }}, - RoleRef: rbacv1.RoleRef{ - Kind: "Role", - Name: "bar", + { + ObjectMeta: metav1.ObjectMeta{ + Name: "testing-sa", + Namespace: "two", + }, + Subjects: []rbacv1.Subject{{ + Name: "circleci", + Kind: "ServiceAccount", + Namespace: "circleci", + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: "cluster-admin", + }, }, - }} + { + ObjectMeta: metav1.ObjectMeta{ + Name: "testing-sa", + Namespace: "three", + }, + Subjects: []rbacv1.Subject{{ + Name: "circleci", + Kind: "ServiceAccount", + Namespace: "circleci", + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: "cluster-admin", + }, + }, + } for _, roleBinding := range roleBindings { _, err := l.clientset.RbacV1().RoleBindings(roleBinding.Namespace).Create(context.Background(), &roleBinding, metav1.CreateOptions{}) @@ -334,22 +435,38 @@ func loadClusterRoleBindings(t *testing.T, l lister) { } func createClusterRoleBindings(t *testing.T, l lister) { - clusterRoleBindings := []rbacv1.ClusterRoleBinding{{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testing", + clusterRoleBindings := []rbacv1.ClusterRoleBinding{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "testing", + }, + Subjects: []rbacv1.Subject{{ + Name: "joe", + Kind: "User", + }, { + Name: "sue", + Kind: "User", + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: "bar", + }, }, - Subjects: []rbacv1.Subject{{ - Name: "joe", - Kind: "User", - }, { - Name: "sue", - Kind: "User", - }}, - RoleRef: rbacv1.RoleRef{ - Kind: "ClusterRole", - Name: "bar", + { + ObjectMeta: metav1.ObjectMeta{ + Name: "circleci-cluster-admin", + }, + Subjects: []rbacv1.Subject{{ + Name: "circleci", + Kind: "ServiceAccount", + Namespace: "circleci", + }}, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: "cluster-admin", + }, }, - }} + } for _, clusterRoleBinding := range clusterRoleBindings { _, err := l.clientset.RbacV1().ClusterRoleBindings().Create(context.Background(), &clusterRoleBinding, metav1.CreateOptions{}) diff --git a/lookup/rbac_subject.go b/lookup/rbac_subject.go index b6f5e50..cc89878 100644 --- a/lookup/rbac_subject.go +++ b/lookup/rbac_subject.go @@ -36,8 +36,11 @@ type simpleRoleSource struct { func (rbacSubj *rbacSubject) addRoleBinding(roleBinding *rbacv1.RoleBinding) { simpleRole := simpleRole{ - Name: roleBinding.RoleRef.Name, - Source: simpleRoleSource{Name: roleBinding.Name, Kind: "RoleBinding"}, + Name: roleBinding.RoleRef.Name, + Source: simpleRoleSource{ + Name: roleBinding.Name, + Kind: "RoleBinding", + }, } simpleRole.Kind = roleBinding.RoleRef.Kind