Skip to content

Commit

Permalink
Merge pull request #45 from garethjevans/missconfigured
Browse files Browse the repository at this point in the history
feat: improvements for invalid role definitions
  • Loading branch information
garethjevans authored Oct 28, 2022
2 parents d0efd2a + a56d1cb commit d97c434
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 81 deletions.
40 changes: 14 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ ServiceAccount/sa-under-test (test-namespace)
│ ├ core.k8s.io
│ │ ├ configmaps verbs=[get watch list] ✔
│ │ ├ pods verbs=[get watch list] ✔
│ │ ├ pods/log verbs=[get watch list] ✔
│ │ ├ pods/log verbs=[get] ✔
│ │ └ services verbs=[get watch list] ✔
│ └ networking.k8s.io
│ └ ingresses verbs=[get] ✔
Expand All @@ -64,33 +64,21 @@ ServiceAccount/sa-under-test (test-namespace)
The plugin will also highlight when configured roles are missing:

```commandLine
❯ kubectl permissions sa-under-test -n test-namespace
⛔ WARNING roles.rbac.authorization.k8s.io "a-missing-role" not found
ServiceAccount/sa-under-test (test-namespace)
├ ClusterRoleBinding/cluster-roles
│ └ ClusterRole/cluster-level-role
│ ├ apps
│ │ ├ deployments verbs=[get watch list] ✔
│ │ └ replicasets verbs=[get watch list] ✔
│ ├ core.k8s.io
│ │ ├ configmaps verbs=[get watch list] ✔
│ │ ├ pods verbs=[get watch list] ✔
│ │ ├ pods/log verbs=[get watch list] ✔
│ │ └ services verbs=[get watch list] ✔
│ └ networking.k8s.io
│ └ ingresses verbs=[get] ✔
├ RoleBinding/missconfigured (test-namespace)
│ └ Role/a-missing-role (a-missing-role) ❌ - MISSING!!
└ RoleBinding/namespaced-roles (test-namespace)
└ Role/namespaced-role (test-namespace)
├ kpack.io
│ ├ builds verbs=[get watch list] ✔
│ └ images verbs=[get watch list] ✔
❯ kubectl permissions invalid-sa
⛔ WARNING roles.rbac.authorization.k8s.io "missing-role" not found
⛔ WARNING API Group bingbong.io does not exist
⛔ WARNING Resource invalid does not exist
ServiceAccount/invalid-sa (test-namespace)
├ RoleBinding/missing-role-binding (test-namespace)
│ └ Role/missing-role (missing-role) ❌ - MISSING!!
└ RoleBinding/missing-role-binding2 (test-namespace)
└ Role/invalid-role (test-namespace)
├ bingbong.io
│ └ something verbs=[get watch list] ❌ (API Group 'bingbong.io' does not exist)
├ source.toolkit.fluxcd.io
│ └ gitrepositories verbs=[get watch list] ✔
│ └ gitrepositories verbs=[laugh] ❌ (Permissions 'laugh' are missing)
└ tekton.dev
├ pipelineruns verbs=[get watch list] ✔
└ taskruns verbs=[get watch list] ✔
└ invalid verbs=[get] ❌ (Resource 'invalid' does not exist)
```

To display the current version of the plugin you can use:
Expand Down
58 changes: 45 additions & 13 deletions example-rbac.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ metadata:
namespace: test-namespace
name: sa-under-test
---
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: test-namespace
name: invalid-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
Expand All @@ -28,8 +34,11 @@ metadata:
name: cluster-level-role
rules:
- apiGroups: ['']
resources: ['pods', 'pods/log', 'services', 'configmaps']
resources: ['pods', 'services', 'configmaps']
verbs: ['get', 'watch', 'list']
- apiGroups: ['']
resources: ['pods/log']
verbs: ['get']
- apiGroups: ['apps']
resources: ['deployments', 'replicasets']
verbs: ['get', 'watch', 'list']
Expand All @@ -43,20 +52,29 @@ metadata:
name: namespaced-role
namespace: test-namespace
rules:
- apiGroups: ['source.toolkit.fluxcd.io']
- apiGroups: ['']
resources:
- gitrepositories
- secrets
verbs: ['get', 'watch', 'list']
- apiGroups: ['kpack.io']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: invalid-role
namespace: test-namespace
rules:
- apiGroups: ['']
resources:
- images
- builds
verbs: ['get', 'watch', 'list']
- apiGroups: ['tekton.dev']
- invalid
verbs: ['get']
- apiGroups: ['bingbong.io']
resources:
- taskruns
- pipelineruns
- something
verbs: ['get', 'watch', 'list']
- apiGroups: ['apps']
resources:
- deployments
verbs: ['laugh']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
Expand All @@ -75,13 +93,27 @@ roleRef:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: missconfigured
name: missing-role-binding
namespace: test-namespace
subjects:
- kind: ServiceAccount
namespace: test-namespace
name: sa-under-test
name: invalid-sa
roleRef:
kind: Role
name: missing-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: missing-role-binding2
namespace: test-namespace
subjects:
- kind: ServiceAccount
namespace: test-namespace
name: invalid-sa
roleRef:
kind: Role
name: a-missing-role
name: invalid-role
apiGroup: rbac.authorization.k8s.io
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/stretchr/objx v0.4.0 // indirect
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
)

Expand Down
4 changes: 3 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,14 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
Expand Down
57 changes: 20 additions & 37 deletions integration/expect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,23 @@ func TestPluginIntegration(t *testing.T) {

response := string(session.Wait(10 * time.Second).Out.Contents())

expected := "\x1b[0;31m⛔ WARNING\x1b[0m roles.rbac.authorization.k8s.io \"a-missing-role\" not found\n" +
expected :=
"ServiceAccount/sa-under-test (test-namespace)\n" +
"\x1b[0;94;40m├\x1b[0m ClusterRoleBinding/cluster-roles\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m ClusterRole/cluster-level-role\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m apps\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m deployments verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m replicasets verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m core.k8s.io\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m configmaps verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m pods verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m pods/log verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m services verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m networking.k8s.io\n\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m ingresses verbs=[get] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m├\x1b[0m RoleBinding/missconfigured (test-namespace)\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m Role/a-missing-role (a-missing-role) ❌ - \x1b[0;31mMISSING!!\x1b[0m\n" +
"\x1b[0;94;40m└\x1b[0m RoleBinding/namespaced-roles (test-namespace)\n" +
" \x1b[0;94;40m└\x1b[0m Role/namespaced-role (test-namespace)\n" +
" \x1b[0;94;40m├\x1b[0m kpack.io\n" +
" \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m builds verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
" \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m images verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
" \x1b[0;94;40m├\x1b[0m source.toolkit.fluxcd.io\n" +
" \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m gitrepositories verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
" \x1b[0;94;40m└\x1b[0m tekton.dev\n" +
" \x1b[0;94;40m├\x1b[0m pipelineruns verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
" \x1b[0;94;40m└\x1b[0m taskruns verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n"
"\x1b[0;94;40m├\x1b[0m ClusterRoleBinding/cluster-roles\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m ClusterRole/cluster-level-role\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m apps\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m deployments verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m replicasets verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m core.k8s.io\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m configmaps verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m pods verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m├\x1b[0m pods/log verbs=[get] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m services verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m networking.k8s.io\n\x1b[0;94;40m│\x1b[0m \x1b[0;94;40m└\x1b[0m ingresses verbs=[get] \x1b[0;32m✔ \x1b[0m\n" +
"\x1b[0;94;40m└\x1b[0m RoleBinding/namespaced-roles (test-namespace)\n" +
" \x1b[0;94;40m└\x1b[0m Role/namespaced-role (test-namespace)\n" +
" \x1b[0;94;40m└\x1b[0m core.k8s.io\n" +
" \x1b[0;94;40m└\x1b[0m secrets verbs=[get watch list] \x1b[0;32m✔ \x1b[0m\n"

Expect(strings.TrimSpace(response)).To(Equal(strings.TrimSpace(expected)))
}
Expand All @@ -72,8 +64,7 @@ func TestPluginIntegrationNoColor(t *testing.T) {
}

response := string(session.Wait(10 * time.Second).Out.Contents())
expected := `!! WARNING roles.rbac.authorization.k8s.io "a-missing-role" not found
ServiceAccount/sa-under-test (test-namespace)
expected := `ServiceAccount/sa-under-test (test-namespace)
├ ClusterRoleBinding/cluster-roles
│ └ ClusterRole/cluster-level-role
│ ├ apps
Expand All @@ -82,22 +73,14 @@ ServiceAccount/sa-under-test (test-namespace)
│ ├ core.k8s.io
│ │ ├ configmaps verbs=[get watch list] ✔
│ │ ├ pods verbs=[get watch list] ✔
│ │ ├ pods/log verbs=[get watch list] ✔
│ │ ├ pods/log verbs=[get] ✔
│ │ └ services verbs=[get watch list] ✔
│ └ networking.k8s.io
│ └ ingresses verbs=[get] ✔
├ RoleBinding/missconfigured (test-namespace)
│ └ Role/a-missing-role (a-missing-role) X - MISSING!!
└ RoleBinding/namespaced-roles (test-namespace)
└ Role/namespaced-role (test-namespace)
├ kpack.io
│ ├ builds verbs=[get watch list] ✔
│ └ images verbs=[get watch list] ✔
├ source.toolkit.fluxcd.io
│ └ gitrepositories verbs=[get watch list] ✔
└ tekton.dev
├ pipelineruns verbs=[get watch list] ✔
└ taskruns verbs=[get watch list] ✔
└ core.k8s.io
└ secrets verbs=[get watch list] ✔
`
Expect(strings.TrimSpace(response)).To(Equal(strings.TrimSpace(expected)))
}
Expand Down
Loading

0 comments on commit d97c434

Please sign in to comment.