Skip to content

Commit

Permalink
fix(kubernetes): improve in-cluster execution (prowler-cloud#3397)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrCloudSec authored Feb 28, 2024
1 parent 6197cf7 commit 3e6b76d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 10 deletions.
11 changes: 11 additions & 0 deletions job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Pod
metadata:
name: prowler
spec:
containers:
- name: prowler
image: docker.io/prowler/kubernetes
command: ["prowler"]
args: ["kubernetes"]
imagePullPolicy: Never
11 changes: 11 additions & 0 deletions prowler-role.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prowler-read-cluster
rules:
- apiGroups: [""]
resources: ["pods", "configmaps", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings", "rolebindings", "clusterroles", "roles"]
verbs: ["get", "list", "watch"]
12 changes: 12 additions & 0 deletions prowler-rolebinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prowler-read-cluster-default-sa
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: prowler-read-cluster
subjects:
- kind: ServiceAccount
name: default
namespace: default
9 changes: 8 additions & 1 deletion prowler/providers/kubernetes/kubernetes_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@ def __set_credentials__(self, kubeconfig_file, context):
config.load_kube_config(
config_file=os.path.abspath(kubeconfig_file), context=context
)
context = config.list_kube_config_contexts()[0][0]
else:
# Otherwise try to load in-cluster config
config.load_incluster_config()
context = config.list_kube_config_contexts()[0][0]
context = {
"name": "In-Cluster",
"context": {
"cluster": "in-cluster", # Placeholder, as the real cluster name is not available
"user": "service-account-name", # Also a placeholder
},
}
return client.ApiClient(), context
except Exception as error:
logger.critical(
Expand Down
45 changes: 36 additions & 9 deletions prowler/providers/kubernetes/kubernetes_provider_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,17 @@ def setup_session(self, kubeconfig_file, context):
config.load_kube_config(
config_file=os.path.abspath(kubeconfig_file), context=context
)
context = config.list_kube_config_contexts()[0][0]
else:
# Otherwise try to load in-cluster config
config.load_incluster_config()
context = config.list_kube_config_contexts()[0][0]
context = {
"name": "In-Cluster",
"context": {
"cluster": "in-cluster", # Placeholder, as the real cluster name is not available
"user": "service-account-name", # Also a placeholder
},
}
return client.ApiClient(), context
except Exception as error:
logger.critical(
Expand Down Expand Up @@ -96,18 +103,38 @@ def get_context_user_roles(self):
)
sys.exit(1)

def print_credentials(self):
def get_pod_current_namespace(self):
"""Retrieve the current namespace from the pod's mounted service account info."""
try:
with open(
"/var/run/secrets/kubernetes.io/serviceaccount/namespace", "r"
) as f:
return f.read().strip()
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
return "default"

def print_credentials(self):
# Get the current context
cluster_name = self.context.get("context").get("cluster")
user_name = self.context.get("context").get("user")
namespace = self.context.get("namespace", "default")
roles = self.get_context_user_roles()
roles_str = ", ".join(roles) if roles else "No associated Roles"
if self.context.get("name") == "In-Cluster":
report = f"""
This report is being generated using the Kubernetes configuration below:
Kubernetes Pod: {Fore.YELLOW}[prowler]{Style.RESET_ALL} Namespace: {Fore.YELLOW}[{self.get_pod_current_namespace()}]{Style.RESET_ALL}
"""
print(report)
else:
cluster_name = self.context.get("context").get("cluster")
user_name = self.context.get("context").get("user")
namespace = self.context.get("namespace", "default")
roles = self.get_context_user_roles()
roles_str = ", ".join(roles) if roles else "No associated Roles"

report = f"""
report = f"""
This report is being generated using the Kubernetes configuration below:
Kubernetes Cluster: {Fore.YELLOW}[{cluster_name}]{Style.RESET_ALL} User: {Fore.YELLOW}[{user_name}]{Style.RESET_ALL} Namespace: {Fore.YELLOW}[{namespace}]{Style.RESET_ALL} Roles: {Fore.YELLOW}[{roles_str}]{Style.RESET_ALL}
"""
print(report)
print(report)

0 comments on commit 3e6b76d

Please sign in to comment.