Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- GCP and OCI simulation providers now handle partial final pagination pages without indexing past the available instances.
- Non-positive `pageSize` configuration values now emit a warning and use the provider default instead of reaching provider APIs and simulation pagination loops.

### Security

- Main Topograph API server ClusterRole rules are gated by the selected engine and provider: `nodes`, `pods`, `daemonsets`, and `configmaps` permissions render only when the engine or provider reaches the Kubernetes API, and the ClusterRole and ClusterRoleBinding are omitted entirely for non-Kubernetes combinations such as the `test` provider with the `slurm` engine.

---

## [v1.0.0] - 2026-08-18
Expand Down
52 changes: 39 additions & 13 deletions charts/topograph/templates/rbac.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
{{- if .Values.rbac.create -}}
{{- $engine := .Values.engine.name -}}
{{- $provider := .Values.provider.name -}}
{{- /*
pods/exec is needed by providers that exec inside pods, and by Slinky only for
legacy partition discovery through `scontrol show partition` in the controller
pod (falling back to a login pod when present).
Slinky skips that path when dynamic nodes are enabled or when a topology entry
already supplies nodes, a pod selector, or the default flat topology.
*/ -}}
{{- $needsPodExec := dict "value" false -}}
{{- if eq .Values.provider.name "infiniband-k8s" -}}
{{- $_ := set $needsPodExec "value" true -}}
{{- $needsPodExec := false -}}
{{- if eq $provider "infiniband-k8s" -}}
{{- $needsPodExec = true -}}
{{- end -}}
{{- if eq .Values.engine.name "slinky" -}}
{{- if eq $engine "slinky" -}}
{{- $params := default dict .Values.engine.params -}}
{{- if not (get $params "useDynamicNodes") -}}
{{- range $topology := (default dict (get $params "topologies")) -}}
Expand All @@ -20,41 +22,64 @@ already supplies nodes, a pod selector, or the default flat topology.
{{- $hasPodSelector := and $podSelector (or (get $podSelector "matchLabels") (get $podSelector "matchExpressions")) -}}
{{- $isDefaultFlat := and (get $spec "clusterDefault") (eq (get $spec "plugin") "topology/flat") (not (get $spec "partition")) -}}
{{- if and (not $hasNodes) (not $hasPodSelector) (not $isDefaultFlat) -}}
{{- $_ := set $needsPodExec "value" true -}}
{{- $needsPodExec = true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- /*
Gate the main ClusterRole rules by engine/provider. The API server only needs
Kubernetes API access when the selected engine or provider actually calls the
API.
*/ -}}
{{- $needsNodes := false -}}
{{- if or (eq $engine "k8s") (eq $engine "slinky") (eq $engine "nfd") (eq $provider "dra") (eq $provider "infiniband-k8s") -}}
{{- $needsNodes = true -}}
{{- end -}}
{{- $needsPods := false -}}
{{- if or (eq $engine "slinky") (eq $provider "infiniband-k8s") -}}
{{- $needsPods = true -}}
{{- end -}}
{{- $needsDaemonSets := false -}}
{{- if eq $provider "infiniband-k8s" -}}
{{- $needsDaemonSets = true -}}
{{- end -}}
{{- $needsConfigMaps := false -}}
{{- if eq $engine "slinky" -}}
{{- $needsConfigMaps = true -}}
{{- end -}}
{{- if or $needsNodes $needsPods $needsDaemonSets $needsConfigMaps $needsPodExec }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "topograph.rbacName" . }}
rules:
{{- if $needsPods }}
- apiGroups: [""]
resources: [pods]
verbs: [list]
{{- if $needsPodExec.value }}
{{- end }}
{{- if $needsPodExec }}
- apiGroups: [""]
resources: [pods/exec]
verbs: [create]
{{- end }}
{{- if $needsNodes }}
- apiGroups: [""]
resources: [nodes]
verbs: [get,list]
{{- if eq .Values.engine.name "k8s" }}
{{- if or (eq $engine "k8s") (eq $engine "slinky") }}
- apiGroups: [""]
resources: [nodes]
verbs: [patch]
{{- end }}
{{- if eq .Values.engine.name "slinky" }}
- apiGroups: [""]
resources: [nodes]
verbs: [patch]
{{- end }}
{{- if $needsDaemonSets }}
- apiGroups: [apps]
resources: [daemonsets]
verbs: [get]
{{- if eq .Values.engine.name "slinky" }}
{{- end }}
{{- if $needsConfigMaps }}
- apiGroups: [""]
resources: [configmaps]
verbs: [create,get,update]
Expand All @@ -73,7 +98,8 @@ roleRef:
kind: ClusterRole
name: {{ include "topograph.rbacName" . }}
apiGroup: rbac.authorization.k8s.io
{{- if eq .Values.engine.name "nfd" }}
{{- end }}
{{- if eq $engine "nfd" }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,6 @@ renders default values.yaml:
metadata:
name: chart-ci-topograph
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
Expand All @@ -432,12 +426,6 @@ renders default values.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
15: |
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down Expand Up @@ -1011,12 +999,6 @@ renders values.k8s.gateway-api-example.yaml:
metadata:
name: chart-ci-topograph
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
Expand All @@ -1030,12 +1012,6 @@ renders values.k8s.gateway-api-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
16: |
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down Expand Up @@ -1623,12 +1599,6 @@ renders values.k8s.gcp-federated-workload-identity-example.yaml:
metadata:
name: chart-ci-topograph
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
Expand All @@ -1642,12 +1612,6 @@ renders values.k8s.gcp-federated-workload-identity-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
15: |
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down Expand Up @@ -2221,12 +2185,6 @@ renders values.k8s.gcp-service-account-example.yaml:
metadata:
name: chart-ci-topograph
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
Expand All @@ -2240,12 +2198,6 @@ renders values.k8s.gcp-service-account-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
15: |
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
Expand Down Expand Up @@ -3455,12 +3407,6 @@ renders values.slinky.block-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- apiGroups:
- ""
resources:
Expand Down Expand Up @@ -4080,12 +4026,6 @@ renders values.slinky.partition-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- apiGroups:
- ""
resources:
Expand Down Expand Up @@ -4680,12 +4620,6 @@ renders values.slinky.tree-example.yaml:
- nodes
verbs:
- patch
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- apiGroups:
- ""
resources:
Expand Down
Loading
Loading