# Created if cluster resources are not omitted
{{- if or (eq .Values.global.resourceScope "all") (eq .Values.global.resourceScope "cluster") }}
# Created if this is not a remote istiod, OR if it is and is also a config cluster
{{- if or (not .Values.istiodRemote.enabled) (and .Values.istiodRemote.enabled (or .Values.global.configCluster .Values.istiodRemote.enabledLocalInjectorIstiod)) }}
{{ $mcsAPIGroup := or .Values.env.MCS_API_GROUP "multicluster.x-k8s.io" }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: istiod-clusterrole{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }}
  labels:
    app: istiod
    release: {{ .Release.Name }}
    app.kubernetes.io/name: "istiod"
    {{- include "istio.labels" . | nindent 4 }}
rules:
  # sidecar injection controller
  - apiGroups: ["admissionregistration.k8s.io"]
    resources: ["mutatingwebhookconfigurations"]
    verbs: ["get", "list", "watch", "update", "patch"]

  # configuration validation webhook controller
  - apiGroups: ["admissionregistration.k8s.io"]
    resources: ["validatingwebhookconfigurations"]
    verbs: ["get", "list", "watch", "update"]

  # istio configuration
  # removing CRD permissions can break older versions of Istio running alongside this control plane (https://github.com/istio/istio/issues/29382)
  # please proceed with caution
  - apiGroups: ["config.istio.io", "security.istio.io", "networking.istio.io", "authentication.istio.io", "rbac.istio.io", "telemetry.istio.io", "extensions.istio.io"]
    verbs: ["get", "watch", "list"]
    resources: ["*"]
{{- if .Values.global.istiod.enableAnalysis }}
  - apiGroups: ["config.istio.io", "security.istio.io", "networking.istio.io", "authentication.istio.io", "rbac.istio.io", "telemetry.istio.io", "extensions.istio.io"]
    verbs: ["update", "patch"]
    resources:
    - authorizationpolicies/status
    - destinationrules/status
    - envoyfilters/status
    - gateways/status
    - peerauthentications/status
    - proxyconfigs/status
    - requestauthentications/status
    - serviceentries/status
    - sidecars/status
    - telemetries/status
    - virtualservices/status
    - wasmplugins/status
    - workloadentries/status
    - workloadgroups/status
{{- end }}
  - apiGroups: ["networking.istio.io"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "workloadentries" ]
  - apiGroups: ["networking.istio.io"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "workloadentries/status",  "serviceentries/status" ]
  - apiGroups: ["security.istio.io"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "authorizationpolicies/status" ]
  - apiGroups: [""]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "services/status" ]

  # auto-detect installed CRD definitions
  - apiGroups: ["apiextensions.k8s.io"]
    resources: ["customresourcedefinitions"]
    verbs: ["get", "list", "watch"]

  # discovery and routing
  - apiGroups: [""]
    resources: ["pods", "nodes", "services", "namespaces", "endpoints"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["discovery.k8s.io"]
    resources: ["endpointslices"]
    verbs: ["get", "list", "watch"]

{{- if .Values.taint.enabled }}
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["patch"]
{{- end }}

  # ingress controller
{{- if .Values.global.istiod.enableAnalysis }}
  - apiGroups: ["extensions", "networking.k8s.io"]
    resources: ["ingresses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["extensions", "networking.k8s.io"]
    resources: ["ingresses/status"]
    verbs: ["*"]
{{- end}}
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses", "ingressclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["ingresses/status"]
    verbs: ["*"]

  # required for CA's namespace controller
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["create", "get", "list", "watch", "update"]

  # Istiod and bootstrap.
{{- $omitCertProvidersForClusterRole := list "istiod" "custom" "none"}}
{{- if or .Values.env.EXTERNAL_CA (not (has .Values.global.pilotCertProvider $omitCertProvidersForClusterRole)) }}
  - apiGroups: ["certificates.k8s.io"]
    resources:
      - "certificatesigningrequests"
      - "certificatesigningrequests/approval"
      - "certificatesigningrequests/status"
    verbs: ["update", "create", "get", "delete", "watch"]
  - apiGroups: ["certificates.k8s.io"]
    resources:
      - "signers"
    resourceNames:
{{- range .Values.global.certSigners }}
    - {{ . | quote }}
{{- end }}
    verbs: ["approve"]
{{- end}}
{{- if eq (.Values.env).ENABLE_CLUSTER_TRUST_BUNDLE_API true }}
  - apiGroups: ["certificates.k8s.io"]
    resources: ["clustertrustbundles"]
    verbs: ["update", "create", "delete", "list", "watch", "get"]
  - apiGroups: ["certificates.k8s.io"]
    resources: ["signers"]
    resourceNames: ["istio.io/istiod-ca"]
    verbs: ["attest"]
{{- end }}

  # Used by Istiod to verify the JWT tokens
  - apiGroups: ["authentication.k8s.io"]
    resources: ["tokenreviews"]
    verbs: ["create"]

  # Used by Istiod to verify gateway SDS
  - apiGroups: ["authorization.k8s.io"]
    resources: ["subjectaccessreviews"]
    verbs: ["create"]

  # Use for Kubernetes Service APIs
  - apiGroups: ["gateway.networking.k8s.io", "gateway.networking.x-k8s.io"]
    resources: ["*"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["gateway.networking.x-k8s.io"]
    resources:
    - xbackendtrafficpolicies/status
    - xlistenersets/status
    verbs: ["update", "patch"]
  - apiGroups: ["gateway.networking.k8s.io"]
    resources:
    - backendtlspolicies/status
    - gatewayclasses/status
    - gateways/status
    - grpcroutes/status
    - httproutes/status
    - referencegrants/status
    - tcproutes/status
    - tlsroutes/status
    - udproutes/status
    verbs: ["update", "patch"]
  - apiGroups: ["gateway.networking.k8s.io"]
    resources: ["gatewayclasses"]
    verbs: ["create", "update", "patch", "delete"]
  - apiGroups: ["inference.networking.k8s.io"]
    resources: ["inferencepools"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["inference.networking.k8s.io"]
    resources: ["inferencepools/status"]
    verbs: ["update", "patch"]

  # Needed for multicluster secret reading, possibly ingress certs in the future
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "watch", "list"]

  # Used for MCS serviceexport management
  - apiGroups: ["{{ $mcsAPIGroup }}"]
    resources: ["serviceexports"]
    verbs: [ "get", "watch", "list", "create", "delete"]

  # Used for MCS serviceimport management
  - apiGroups: ["{{ $mcsAPIGroup }}"]
    resources: ["serviceimports"]
    verbs: ["get", "watch", "list"]
---
{{- if not (eq (toString .Values.env.PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER) "false") }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: istiod-gateway-controller{{- if not (eq .Values.revision "")}}-{{ .Values.revision }}{{- end }}-{{ .Release.Namespace }}
  labels:
    app: istiod
    release: {{ .Release.Name }}
    app.kubernetes.io/name: "istiod"
    {{- include "istio.labels" . | nindent 4 }}
rules:
  - apiGroups: ["apps"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "deployments" ]
  - apiGroups: ["autoscaling"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "horizontalpodautoscalers" ]
  - apiGroups: ["policy"]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "poddisruptionbudgets" ]
  - apiGroups: [""]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "services" ]
  - apiGroups: [""]
    verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
    resources: [ "serviceaccounts"]
{{- end }}
{{- end }}
{{- end }}