aquasecurity / kubectl-who-can

Show who has RBAC permissions to perform actions on different resources in Kubernetes
Apache License 2.0
848 stars 81 forks source link

[feature] Add a JSON output flag #72

Closed sudermanjr closed 3 years ago

sudermanjr commented 4 years ago

What would you like to be added

JSON output of the information

Why is this needed

It would be quite useful to be able to consume this information in automations. In addition, json would allow me to parse the CLI output easier in some cases.

Gituser143 commented 4 years ago

Hi! Can I work on this issue?

danielpacak commented 4 years ago

Hi! Can I work on this issue?

👋 @Gituser143 Sure thing! May I suggest that you start with JSON output proposal so we can review it before the actual code is written? We can use the comments below to review your JSON schema proposal. Thanks!

Gituser143 commented 4 years ago

I was thinking along the lines of

{
  cluster-role-binding-value : {
    subject: value
    type: value
    namespace: value
  },
  cluster-role-binding-value-2 : {
    subject: value
    type: value
    namespace: value
  }
}

I'd use a map[string]vals where vals is of type struct with the mentioned fields. Is this fair?

Gituser143 commented 4 years ago

@danielpacak Is the above format good enough?

Gituser143 commented 4 years ago

@danielpacak It's been a while. Can I work on this?

danielpacak commented 4 years ago

Sorry @Gituser143 for delay in response, but we're busy with many Hacktoberfest PR floating into our other repositories. This repository is excluded from the list, but if you want to proceed anyhow I'd like you to elaborate on the example above. For example, let's think how the following output can be represented in json/yaml:

$ kubectl who-can get pod -o wide
ROLEBINDING         ROLE                     NAMESPACE           SUBJECT             TYPE            SA-NAMESPACE
starboard-operator  Role/starboard-operator  starboard-operator  starboard-operator  ServiceAccount  starboard-operator

CLUSTERROLEBINDING                           ROLE                                                     SUBJECT                    TYPE            SA-NAMESPACE
cluster-admin                                ClusterRole/cluster-admin                                system:masters             Group
csp-role-binding                             ClusterRole/csp-cluster-role                             csp-sa                     ServiceAccount  aqua
minikube-rbac                                ClusterRole/cluster-admin                                default                    ServiceAccount  kube-system
system:controller:deployment-controller      ClusterRole/system:controller:deployment-controller      deployment-controller      ServiceAccount  kube-system
system:controller:endpoint-controller        ClusterRole/system:controller:endpoint-controller        endpoint-controller        ServiceAccount  kube-system
system:controller:generic-garbage-collector  ClusterRole/system:controller:generic-garbage-collector  generic-garbage-collector  ServiceAccount  kube-system
system:controller:namespace-controller       ClusterRole/system:controller:namespace-controller       namespace-controller       ServiceAccount  kube-system
system:controller:persistent-volume-binder   ClusterRole/system:controller:persistent-volume-binder   persistent-volume-binder   ServiceAccount  kube-system
system:controller:pvc-protection-controller  ClusterRole/system:controller:pvc-protection-controller  pvc-protection-controller  ServiceAccount  kube-system
system:controller:statefulset-controller     ClusterRole/system:controller:statefulset-controller     statefulset-controller     ServiceAccount  kube-system
system:kube-scheduler                        ClusterRole/system:kube-scheduler                        system:kube-scheduler      User
Gituser143 commented 4 years ago

we're busy with many Hacktoberfest PR floating into our other repositories

Oops, I'm sorry for nagging! Since there's quite a lot on your plate already, can I work on this after October? I'll think of appropriate JSON formats and post them here as comments by then.

I hope that's okay?

danielpacak commented 3 years ago

we're busy with many Hacktoberfest PR floating into our other repositories

Oops, I'm sorry for nagging! Since there's quite a lot on your plate already, can I work on this after October? I'll think of appropriate JSON formats and post them here as comments by then.

I hope that's okay?

👋 @Gituser143 Sorry for late reply. Feel free to work on this one. We'll alway reply in async mode as soon as we can.

Gituser143 commented 3 years ago

Hey @danielpacak, I happen to have a few exams I have to write, would it be okay if I took this up after maybe a week or so? :grimacing:

danielpacak commented 3 years ago

Hey @danielpacak, I happen to have a few exams I have to write, would it be okay if I took this up after maybe a week or so? 😬

Sure. No problem. Whenever you have time to contribute we'll work with you. And good luck with the exams 💪

Gituser143 commented 3 years ago

Hey @danielpacak! I took a look at cmd/printer.go and noticed that either role bindings or cluster role bindings are all that are printed (either normally or wide). Since this is the case, would the below JSON format be suitable? If I'm missing something do let me know.

{
  "RoleBindings": [
    {
      "ROLEBINDING": "Value",
      "ROLE": "Value",
      "NAMESPACE": "Value",
      "SUBJECT": "Value",
      "TYPE": "Value",
      "SA-NAMESPACE": "Value"
    },
    {
      "ROLEBINDING": "Value",
      "ROLE": "Value",
      "NAMESPACE": "Value",
      "SUBJECT": "Value",
      "TYPE": "Value",
      "SA-NAMESPACE": "Value"
    }
  ],

  "ClusterRoleBindings": [
    {
      "CLUSTERROLEBINDING": "Value",
      "ROLE": "Value",
      "SUBJECT": "Value",
      "TYPE": "Value",
      "SA-NAMESPACE": "Value"
    },
    {
      "CLUSTERROLEBINDING": "Value",
      "ROLE": "Value",
      "SUBJECT": "Value",
      "TYPE": "Value",
      "SA-NAMESPACE": "Value"
    }
  ]
}

PS: I'm extremely sorry for the delay :grimacing:

Gituser143 commented 3 years ago

Hey @danielpacak, is the above format alright? I'd like to get some sort of confirmation before opening a PR...

danielpacak commented 3 years ago

Hey @Gituser143 I think it's a good start, but I'd make this output as similar to built-in Kubernetes RBAC objects as possible.

The first thing would be to use the same camelCase for JSON properties as the output of kubectl command. Check for example how it looks for kubectl get clusterrolebindings cluster-admin -o json.

Notice that a given RoleBinding might reference Role or ClusterRole. Therefore I'd consider reusing existing roleRef and subject structs that are already defined in the client-go module, i.e.:

{
  "roleBindings": [
    {
      "name": "my-binding",
      "roleRef": {
        "kind": "ClusterRole",
        "name": "cluster-admin",
        "apiGroup": "rbac.authorization.k8s.io"
      },
      "subject": {
        "kind": "Group",
        "name": "some-group",
        "apiGroup": "rbac.authorization.k8s.io"
      }
    }
  ],
  "clusterRoleBindings": [
    {
      "name": "my-cluster-binding",
      "roleRef": {
        "kind": "ClusterRole",
        "name": "cluster-admin",
        "apiGroup": "rbac.authorization.k8s.io"
      },
      "subject": {
        "kind": "ServiceAccount",
        "name": "my-sa",
        "namespace": "my-namespace",
        "apiGroup": "rbac.authorization.k8s.io"
      }
    }
  ]  
}
Gituser143 commented 3 years ago

Sounds good! I'll send in a PR soon.

Gituser143 commented 3 years ago

Hey @danielpacak, I've got a few things I'm not sure of which I was hoping you could clarify for me.

  1. Both RoleBinding and ClusterRolerBinding have fields of metav1.TypeMeta and metav1.ListMeta. Should these be exported too?

  2. I'm not entirely sure whether to create a flag (command line option) to export data or to add functionality to the -o option itself. What do you suggest I do here?

EDIT: I've made a PR #81, for this. I've currently ignored the two mentioned metadata fields and added a new -e flag for export.

Gituser143 commented 3 years ago

Hi @danielpacak, it's been a while since I opened the PR, I need some help with the testing, could I get some pointers?

WhiteBowlerHat commented 1 year ago

I ran the command : kubectl-who-can --kubeconfig <config> create bindings

which is successfully running :

CLUSTERROLEBINDING | SUBJECT | TYPE | SA-NAMESPACE cluster-admin | system:masters | Group cluster-reconciler-flux-system | kustomize-controller | ServiceAccount | flux-system cluster-reconciler-flux-system | helm-controller | ServiceAccount | flux-system clusterrolebinding-5n4fz | | Group

However when I add the "-o json" kubectl-who-can --kubeconfig <config> -o json create bindings

The command outputs the following : { "name": "cluster-admin", "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "cluster-admin" }, "subjects": [ { "kind": "Group", "apiGroup": "rbac.authorization.k8s.io", "name": "system:masters" } ] }, { "name": "cluster-reconciler-flux-system", "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "cluster-admin" }, "subjects": [ { "kind": "ServiceAccount", "name": "kustomize-controller", "namespace": "flux-system" }, { "kind": "ServiceAccount", "name": "helm-controller", "namespace": "flux-system" } ] }, { "name": "clusterrolebinding-5n4fz", "roleRef": { "apiGroup": "rbac.authorization.k8s.io", "kind": "ClusterRole", "name": "cluster-owner" }, "subjects": [ { "kind": "Group", "apiGroup": "rbac.authorization.k8s.io", "name": "googleoauth_group://03rdcrjn0zs73n4" } ] }

A clusterrole is missing, which is normal because json objects cannot have the same name. In order to fix the problem maybe the program should put an ID