{{ if .Values.multicluster.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-cluster-gateway
  namespace: {{ .Release.Namespace }}
  labels:
  {{- include "kubevela.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.multicluster.clusterGateway.replicaCount }}
  selector:
    matchLabels:
    {{- include "kubevela-cluster-gateway.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      annotations:
        prometheus.io/path: /metrics
        prometheus.io/port: "9443"
        prometheus.io/scrape: "true"
        prometheus.io/scheme: "https"
      labels:
      {{- include "kubevela-cluster-gateway.selectorLabels" . | nindent 8 }}
    spec:
      {{- with .Values.imagePullSecrets }}
      imagePullSecrets:
      {{- toYaml . | nindent 8 }}
      {{- end }}
      serviceAccountName: {{ include "kubevela.serviceAccountName" . }}
      securityContext:
      {{- toYaml .Values.podSecurityContext | nindent 8 }}
      containers:
        - name: {{ include "kubevela.fullname" . }}-cluster-gateway
          securityContext:
          {{- toYaml .Values.securityContext | nindent 12 }}
          args:
            - "apiserver"
            - "--secure-port={{ .Values.multicluster.clusterGateway.port }}"
            - "--secret-namespace={{ .Release.Namespace }}"
            - "--feature-gates=APIPriorityAndFairness=false,ClientIdentityPenetration={{ .Values.authentication.enabled }}"
            - "--cluster-gateway-proxy-config=/etc/proxy-config/config.yaml"
            {{- if .Values.multicluster.clusterGateway.secureTLS.enabled }}
            - "--tls-cert-file={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}/tls.crt"
            - "--tls-private-key-file={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}/tls.key"
            {{- end }}
            - "--authorization-always-allow-paths=/healthz,/readyz,/livez,/metrics"
          image: {{ .Values.imageRegistry }}{{ .Values.multicluster.clusterGateway.image.repository }}:{{ .Values.multicluster.clusterGateway.image.tag }}
          imagePullPolicy: {{ .Values.multicluster.clusterGateway.image.pullPolicy }}
          resources:
          {{- toYaml .Values.multicluster.clusterGateway.resources | nindent 12 }}
          ports:
            - containerPort: {{ .Values.multicluster.clusterGateway.port }}
          volumeMounts:
            - mountPath: /etc/proxy-config
              name: proxy-config
          {{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
            - mountPath: {{ .Values.multicluster.clusterGateway.secureTLS.certPath }}
              name: tls-cert-vol
              readOnly: true
          {{- end }}
      volumes:
        - configMap:
            defaultMode: 420
            name: {{ .Release.Name }}-cluster-gateway-proxy-config
          name: proxy-config
      {{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
        - name: tls-cert-vol
          secret:
            defaultMode: 420
            secretName: {{ template "kubevela.fullname" . }}-cluster-gateway-tls-v2
      {{ end }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
      {{- toYaml . | nindent 8 }}
      {{- end }}
      affinity:
      {{ if .Values.affinity }}
        {{- toYaml .Values.affinity | nindent 8 }}
      {{ else }}
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - podAffinityTerm:
                labelSelector:
                  matchLabels:
                    {{- include "kubevela-cluster-gateway.selectorLabels" . | nindent 20 }}
                topologyKey: kubernetes.io/hostname
              weight: 100
      {{ end }}
      {{- with .Values.tolerations }}
      tolerations:
      {{- toYaml . | nindent 8 }}
      {{- end }}
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-cluster-gateway-proxy-config
  namespace: {{ .Release.Namespace }}
data:
  config.yaml: |
    apiVersion: cluster.core.oam.dev/v1alpha1
    kind: ClusterGatewayProxyConfiguration
    spec:
      clientIdentityExchanger:
        rules:
          - name: super-user
            source:
              group: kubevela:ux
            type: PrivilegedIdentityExchanger
---
apiVersion: v1
kind: Service
metadata:
  name: {{ .Release.Name }}-cluster-gateway-service
  namespace: {{ .Release.Namespace }}
spec:
  selector:
  {{- include "kubevela-cluster-gateway.selectorLabels" . | nindent 4 }}
  ports:
    - protocol: TCP
      port: {{ .Values.multicluster.clusterGateway.port }}
      targetPort: {{ .Values.multicluster.clusterGateway.port }}
      name: default
---
# 1.  Check whether APIService ""v1alpha1.cluster.core.oam.dev" is already present in the cluster
# 2.a If the APIService doesn't exist, create it.
# 2.b If the APIService exists without helm-chart related annotation, skip creating it to the
#     cluster because the APIService can be managed by an external controller.
# 2.c If the APIService exists with valid helm-chart annotations, which means that the APIService
#     is previously managed by helm commands, hence update the APIService consistently.
{{ $apiSvc := (lookup "apiregistration.k8s.io/v1" "APIService" "" "v1alpha1.cluster.core.oam.dev") }}
{{ $shouldAdopt := (not $apiSvc) }}
{{ if not $shouldAdopt }}
  {{ if $apiSvc.metadata.annotations }}
    {{ $shouldAdopt = (index ($apiSvc).metadata.annotations "meta.helm.sh/release-name") }}
  {{ end }}
{{ end }}
{{ if $shouldAdopt }}
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
  name: v1alpha1.cluster.core.oam.dev
  annotations:
    {{- if and .Values.multicluster.clusterGateway.secureTLS.enabled .Values.multicluster.clusterGateway.secureTLS.certManager.enabled }}
    cert-manager.io/inject-ca-from: "{{ .Release.Namespace }}/{{ template "kubevela.fullname" . }}-cluster-gateway-tls-v2"
    {{- end }}
  labels:
    api: cluster-extension-apiserver
    apiserver: "true"
spec:
  version: v1alpha1
  group: cluster.core.oam.dev
  groupPriorityMinimum: 2000
  service:
    name: {{ .Release.Name }}-cluster-gateway-service
    namespace: {{ .Release.Namespace }}
    port: {{ .Values.multicluster.clusterGateway.port }}
  versionPriority: 10
  insecureSkipTLSVerify: {{ not .Values.multicluster.clusterGateway.secureTLS.enabled }}
  {{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
  caBundle: Cg==
  {{ end }}
{{ end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: {{ include "kubevela.fullname" . }}:cluster-gateway:proxy
rules:
  - apiGroups: [ "cluster.core.oam.dev" ]
    resources: [ "clustergateways/proxy" ]
    verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: {{ include "kubevela.fullname" . }}:cluster-gateway:proxy
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: {{ include "kubevela.fullname" . }}:cluster-gateway:proxy
subjects:
  - kind: Group
    name: kubevela:client
    apiGroup: rbac.authorization.k8s.io
  - kind: ServiceAccount
    name: {{ include "kubevela.serviceAccountName" . }}
    namespace: {{ .Release.Namespace }}
{{ end }}
