{{/* validate deprecated options are not being used */}}

{{/* Options deprecated in v1.15 and removed in v1.16 */}}
{{- if or
  (dig "encryption" "keyFile" "" .Values.AsMap)
  (dig "encryption" "mountPath" "" .Values.AsMap)
  (dig "encryption" "secretName" "" .Values.AsMap)
  (dig "encryption" "interface" "" .Values.AsMap)
}}
  {{ fail "encryption.{keyFile,mountPath,secretName,interface} were deprecated in v1.14 and has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}
{{- if or
  ((dig "proxy" "prometheus" "enabled" "" .Values.AsMap) | toString)
  (dig "proxy" "prometheus" "port" "" .Values.AsMap)
}}
  {{ fail "proxy.prometheus.enabled and proxy.prometheus.port were deprecated in v1.14 and has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}
{{- if (dig "endpointStatus" "" .Values.AsMap) }}
  {{ fail "endpointStatus has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}
{{- if (dig "remoteNodeIdentity" "" .Values.AsMap) }}
  {{ fail "remoteNodeIdentity was deprecated in v1.15 and has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}
{{- if (dig "containerRuntime" "integration" "" .Values.AsMap) }}
  {{ fail "containerRuntime.integration was deprecated in v1.14 and has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}
{{- if (dig "etcd" "managed" "" .Values.AsMap) }}
  {{ fail "etcd.managed was deprecated in v1.10 has been removed in v1.16. For details please refer to https://docs.cilium.io/en/v1.16/operations/upgrade/#helm-options" }}
{{- end }}

{{/* Options deprecated in v1.14 and removed in v1.15 */}}
{{- if .Values.tunnel }}
  {{ fail "tunnel was deprecated in v1.14 and has been removed in v1.15. For details please refer to https://docs.cilium.io/en/v1.15/operations/upgrade/#helm-options" }}
{{- end }}
{{- if or (dig "clustermesh" "apiserver" "tls" "ca" "cert" "" .Values.AsMap) (dig "clustermesh" "apiserver" "tls" "ca" "key" "" .Values.AsMap) }}
  {{ fail "clustermesh.apiserver.tls.ca.cert and clustermesh.apiserver.tls.ca.key were deprecated in v1.14 and has been removed in v1.15. For details please refer to https://docs.cilium.io/en/v1.15/operations/upgrade/#helm-options" }}
{{- end }}
{{- if .Values.enableK8sEventHandover }}
  {{ fail "enableK8sEventHandover was deprecated in v1.14 and has been removed in v1.15. For details please refer to https://docs.cilium.io/en/v1.15/operations/upgrade/#helm-options" }}
{{- end }}
{{- if .Values.enableCnpStatusUpdates }}
  {{ fail "enableCnpStatusUpdates was deprecated in v1.14 and has been removed in v1.15. For details please refer to https://docs.cilium.io/en/v1.15/operations/upgrade/#helm-options" }}
{{- end }}

{{/* validate hubble config */}}
{{- if and .Values.hubble.ui.enabled (not .Values.hubble.ui.standalone.enabled) }}
  {{- if not .Values.hubble.relay.enabled }}
    {{ fail "Hubble UI requires .Values.hubble.relay.enabled=true" }}
  {{- end }}
{{- end }}
{{- if and .Values.hubble.ui.enabled .Values.hubble.ui.standalone.enabled .Values.hubble.relay.tls.server.enabled }}
  {{- if not .Values.hubble.ui.standalone.tls.certsVolume }}
    {{ fail "Hubble UI in standalone with Hubble Relay server TLS enabled requires providing .Values.hubble.ui.standalone.tls.certsVolume for mounting client certificates in the backend pod" }}
  {{- end }}
{{- end }}
{{- if .Values.hubble.relay.enabled }}
  {{- if not .Values.hubble.enabled }}
    {{ fail "Hubble Relay requires .Values.hubble.enabled=true" }}
  {{- end }}
{{- end }}

{{/* validate service monitoring CRDs */}}
{{- if or (and .Values.prometheus.enabled .Values.prometheus.serviceMonitor.enabled) (and .Values.operator.prometheus.enabled .Values.operator.prometheus.serviceMonitor.enabled) (and .Values.envoy.prometheus.enabled .Values.envoy.prometheus.serviceMonitor.enabled) (and .Values.hubble.relay.prometheus.enabled .Values.hubble.relay.prometheus.serviceMonitor.enabled) }}
  {{- if not (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") }}
      {{- if not .Values.prometheus.serviceMonitor.trustCRDsExist }}
          {{ fail "Service Monitor requires monitoring.coreos.com/v1 CRDs. Please refer to https://github.com/prometheus-operator/prometheus-operator/blob/main/example/prometheus-operator-crd/monitoring.coreos.com_servicemonitors.yaml or set .Values.prometheus.serviceMonitor.trustCRDsExist=true" }}
      {{- end }}
  {{- end }}
{{- end }}

{{- if and .Values.hubble.enabled .Values.hubble.tls.enabled .Values.hubble.tls.auto.enabled (eq .Values.hubble.tls.auto.method "certmanager") }}
  {{- if not .Values.hubble.tls.auto.certManagerIssuerRef }}
    {{ fail "Hubble TLS certgen method=certmanager requires that user specifies .Values.hubble.tls.auto.certManagerIssuerRef" }}
  {{- end }}
{{- end }}

{{- if and .Values.hubble.redact.http.headers.allow .Values.hubble.redact.http.headers.deny }}
  {{ fail "Only one of .Values.hubble.redact.http.headers.allow, .Values.hubble.redact.http.headers.deny can be specified"}}
{{- end }}

{{- if and (or .Values.externalWorkloads.enabled .Values.clustermesh.useAPIServer) .Values.clustermesh.apiserver.tls.auto.enabled (eq .Values.clustermesh.apiserver.tls.auto.method "certmanager") }}
  {{- if not .Values.clustermesh.apiserver.tls.auto.certManagerIssuerRef }}
    {{ fail "ClusterMesh TLS certgen method=certmanager requires that user specifies .Values.clustermesh.apiserver.tls.auto.certManagerIssuerRef" }}
  {{- end }}
{{- end }}

{{/* validate hubble-ui specific config */}}
{{- if and .Values.hubble.ui.enabled
  (ne .Values.hubble.ui.backend.image.tag "latest")
  (ne .Values.hubble.ui.frontend.image.tag "latest") }}
  {{- if regexReplaceAll "@.*$" .Values.hubble.ui.backend.image.tag "" | trimPrefix "v" | semverCompare "<0.9.0" }}
    {{ fail "Hubble UI requires hubble.ui.backend.image.tag to be '>=v0.9.0'" }}
  {{- end }}
  {{- if regexReplaceAll "@.*$" .Values.hubble.ui.frontend.image.tag "" | trimPrefix "v" | semverCompare "<0.9.0" }}
    {{ fail "Hubble UI requires hubble.ui.frontend.image.tag to be '>=v0.9.0'" }}
  {{- end }}
{{- end }}

{{- if or .Values.ingressController.enabled .Values.gatewayAPI.enabled (eq .Values.loadBalancer.l7.backend "envoy") }}
  {{- if hasKey .Values "l7Proxy" }}
    {{- if not .Values.l7Proxy }}
      {{ fail "Ingress or Gateway API controller or Envoy L7 Load Balancer  requires .Values.l7Proxy to be set to 'true'" }}
    {{- end }}
  {{- end }}
{{- end }}

{{- if and .Values.ingressController.enabled (or (eq .Values.ingressController.service.type "LoadBalancer") (eq .Values.ingressController.service.type "NodePort"))}}
  {{- if not (or (eq .Values.ingressController.service.externalTrafficPolicy "Cluster") (eq .Values.ingressController.service.externalTrafficPolicy "Local")) }}
    {{ fail "Cilium Ingress services of type 'LoadBalancer' or 'NodePort' need an externalTrafficPolicy set to 'Cluster' or 'Local'." }}
  {{- end }}
{{- end }}

{{- if .Values.gatewayAPI.enabled }}
  {{- if not (or (eq .Values.gatewayAPI.externalTrafficPolicy "Cluster") (eq .Values.gatewayAPI.externalTrafficPolicy "Local")) }}
    {{ fail "Cilium GatewayAPI needs an externalTrafficPolicy set to 'Cluster' or 'Local'." }}
  {{- end }}
{{- end }}

{{- if or .Values.envoyConfig.enabled .Values.ingressController.enabled .Values.gatewayAPI.enabled }}
  {{- if or (eq (toString .Values.kubeProxyReplacement) "disabled") (and (not (hasKey .Values "kubeProxyReplacement")) (not (semverCompare ">=1.14" (default "1.14" .Values.upgradeCompatibility)))) }}
    {{ fail "Ingress/Gateway API controller and EnvoyConfig require .Values.kubeProxyReplacement to be explicitly set to 'false' or 'true'" }}
  {{- end }}
{{- end }}

{{- if .Values.authentication.mutual.spire.enabled }}
  {{- if not .Values.authentication.enabled }}
    {{ fail "SPIRE integration requires .Values.authentication.enabled=true and .Values.authentication.mutual.spire.enabled=true" }}
  {{- end }}
{{- end }}

{{/* validate Cilium operator */}}
{{- if or .Values.ciliumEndpointSlice.enabled .Values.enableCiliumEndpointSlice }}
  {{- if eq .Values.disableEndpointCRD true }}
    {{ fail "if Cilium Endpoint Slice is enabled (.Values.ciliumEndpointSlice.enabled=true), it requires .Values.disableEndpointCRD=false" }}
  {{- end }}
{{- end }}

{{/* validate cluster name */}}
{{- if eq .Values.cluster.name "" }}
  {{ fail "The cluster name is invalid: cannot be empty" }}
{{- end }}
{{- if gt (len .Values.cluster.name) 32 }}
  {{ fail "The cluster name is invalid: must not be more than 32 characters" }}
{{- end }}
{{- if not (regexMatch "^([a-z0-9][-a-z0-9]*)?[a-z0-9]$" .Values.cluster.name) }}
  {{ fail "The cluster name is invalid: must consist of lower case alphanumeric characters and '-', and must start and end with an alphanumeric character" }}
{{- end }}
{{- if and (eq .Values.cluster.name "default") (ne (int .Values.cluster.id) 0) }}
  {{ fail "The cluster name is invalid: cannot use default value with cluster.id != 0" }}
{{- end }}
{{ if and
    (ne (index .Values.extraConfig "allow-unsafe-policy-skb-usage") "true")
    (or (and (ge (int .Values.cluster.id) 128) (le (int .Values.cluster.id) 255)) (and (ge (int .Values.cluster.id) 384) (le (int .Values.cluster.id) 511)))
    (or .Values.eni.enabled .Values.alibabacloud.enabled (eq .Values.cni.chainingMode "aws-cni")) -}}
  {{ fail "Cilium is currently affected by a bug that causes traffic matched by network policies to be incorrectly dropped when running in either ENI mode (both AWS and AlibabaCloud) or AWS VPC CNI chaining mode, if the cluster ID is 128-255 (and 384-511 when maxConnectedClusters=511). Please refer to https://github.com/cilium/cilium/issues/21330 for additional details." }}
{{- end }}

{{/* validate clustermesh-apiserver */}}
{{- if .Values.clustermesh.useAPIServer }}
  {{- if and (ne .Values.identityAllocationMode "crd") (ne .Values.identityAllocationMode "doublewrite-readkvstore") (ne .Values.identityAllocationMode "doublewrite-readcrd") }}
    {{ fail (printf "The clustermesh-apiserver cannot be enabled in combination with .Values.identityAllocationMode=%s. To establish a Cluster Mesh, directly configure the parameters to access the remote kvstore through .Values.clustermesh.config" .Values.identityAllocationMode ) }}
  {{- end }}
  {{- if .Values.disableEndpointCRD }}
    {{ fail "The clustermesh-apiserver cannot be enabled in combination with .Values.disableEndpointCRD=true" }}
  {{- end }}
{{- end }}
{{- if .Values.externalWorkloads.enabled }}
  {{- if and (ne .Values.identityAllocationMode "crd") (ne .Values.identityAllocationMode "doublewrite-readkvstore") (ne .Values.identityAllocationMode "doublewrite-readcrd") }}
    {{ fail (printf "External workloads support cannot be enabled in combination with .Values.identityAllocationMode=%s" .Values.identityAllocationMode ) }}
  {{- end }}
  {{- if .Values.disableEndpointCRD }}
    {{ fail "External workloads support cannot be enabled in combination with .Values.disableEndpointCRD=true" }}
  {{- end }}
{{- end }}

{{/*validate ClusterMesh */}}
{{- if and (ne (int .Values.clustermesh.maxConnectedClusters) 255) (ne (int .Values.clustermesh.maxConnectedClusters) 511) }}
  {{- fail "max-connected-clusters must be set to 255 or 511" }}
{{- end }}

{{/*validate Envoy baseID */}}
{{- if not (and (ge (int .Values.envoy.baseID) 0) (le (int .Values.envoy.baseID) 4294967295)) }}
  {{- fail "envoy.baseID must be an int. Supported values 0 - 4294967295" }}
{{- end }}
