# service to expose the ovnkube-db pod
apiVersion: v1
kind: Service
metadata:
  name: ovnkube-db
  namespace: ovn-kubernetes
spec:
  ports:
  - name: north
    port: {{ ovn_nb_port }}
    protocol: TCP
    targetPort: {{ ovn_nb_port }}
  - name: south
    port: {{ ovn_sb_port }}
    protocol: TCP
    targetPort: {{ ovn_sb_port }}
  sessionAffinity: None
  clusterIP: None
  type: ClusterIP

---

# ovndb-raft PodDisruptBudget to prevent majority of ovnkube raft cluster
# nodes from disruption
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: ovndb-raft-pdb
  namespace: ovn-kubernetes
spec:
  minAvailable: {{ ovn_db_minAvailable | default(2) }}
  selector:
    matchLabels:
      name: ovnkube-db

---

# ovnkube-db raft statefulset
# daemonset version 3
# starts ovn NB/SB ovsdb daemons, each in a separate container
#
kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: ovnkube-db
  namespace: ovn-kubernetes
  annotations:
    kubernetes.io/description: |
      This statefulset launches the OVN Northbound/Southbound Database raft clusters.
spec:
  serviceName: ovnkube-db
  podManagementPolicy: "Parallel"
  replicas: {{ ovn_db_replicas | default(3) }}
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      name: ovnkube-db
  template:
    metadata:
      labels:
        ovn-db-pod: "true"
        name: ovnkube-db
        component: network
        type: infra
        kubernetes.io/os: "linux"
      annotations:
        scheduler.alpha.kubernetes.io/critical-pod: ''
    spec:
      terminationGracePeriodSeconds: 30
      imagePullSecrets:
        - name: registry-credentials
      serviceAccountName: ovn
      hostNetwork: true

      # required to be scheduled on node with k8s.ovn.org/ovnkube-db=true label but can
      # only have one instance per node
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: k8s.ovn.org/ovnkube-db
                operator: In
                values:
                - "true"
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: name
                operator: In
                values:
                - ovnkube-db
            topologyKey: kubernetes.io/hostname

      containers:
      # nb-ovsdb - v3
      - name: nb-ovsdb
        image: "{{ ovn_image | default('docker.io/ovnkube/ovn-daemonset:latest') }}"
        imagePullPolicy: "{{ ovn_image_pull_policy | default('IfNotPresent') }}"
        command: ["/root/ovnkube.sh", "nb-ovsdb-raft"]

        readinessProbe:
          exec:
            command: ["/usr/bin/ovn-kube-util", "readiness-probe", "-t", "ovnnb-db-raft"]
          initialDelaySeconds: 30
          timeoutSeconds: 30
          periodSeconds: 60

        securityContext:
          runAsUser: 0
          capabilities:
            add: ["NET_ADMIN"]

        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        # ovn db is stored in the pod in /etc/openvswitch
        # (or in /etc/ovn if OVN from new repository is used)
        # and on the host in /var/lib/openvswitch/
        - mountPath: /etc/openvswitch/
          name: host-var-lib-ovs
        - mountPath: /etc/ovn/
          name: host-var-lib-ovs
        - mountPath: /var/log/openvswitch/
          name: host-var-log-ovs
        - mountPath: /var/log/ovn/
          name: host-var-log-ovs
        - mountPath: /var/run/openvswitch/
          name: host-var-run-ovs
        - mountPath: /var/run/ovn/
          name: host-var-run-ovs
        - mountPath: /ovn-cert
          name: host-ovn-cert
          readOnly: true

        resources:
          requests:
            cpu: 100m
            memory: 300Mi
        env:
        - name: OVN_DAEMONSET_VERSION
          value: "3"
        - name: OVN_LOGLEVEL_NB
          value: "{{ ovn_loglevel_nb }}"
        - name: K8S_APISERVER
          valueFrom:
            configMapKeyRef:
              name: ovn-config
              key: k8s_apiserver
        - name: OVN_KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: K8S_NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: OVN_SSL_ENABLE
          value: "{{ ovn_ssl_en }}"
        - name: OVN_NB_RAFT_ELECTION_TIMER
          value: "{{ ovn_nb_raft_election_timer }}"
        - name: OVN_NB_PORT
          value: "{{ ovn_nb_port }}"
        - name: OVN_NB_RAFT_PORT
          value: "{{ ovn_nb_raft_port }}"
      # end of container

      # sb-ovsdb - v3
      - name: sb-ovsdb
        image: "{{ ovn_image | default('docker.io/ovnkube/ovn-daemonset:latest') }}"
        imagePullPolicy: "{{ ovn_image_pull_policy | default('IfNotPresent') }}"
        command: ["/root/ovnkube.sh", "sb-ovsdb-raft"]

        readinessProbe:
          exec:
            command: ["/usr/bin/ovn-kube-util", "readiness-probe", "-t", "ovnsb-db-raft"]
          initialDelaySeconds: 30
          timeoutSeconds: 30
          periodSeconds: 60

        securityContext:
          runAsUser: 0
          capabilities:
            add: ["NET_ADMIN"]

        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        # ovn db is stored in the pod in /etc/openvswitch
        # (or in /etc/ovn if OVN from new repository is used)
        # and on the host in /var/lib/openvswitch/
        - mountPath: /etc/openvswitch/
          name: host-var-lib-ovs
        - mountPath: /etc/ovn/
          name: host-var-lib-ovs
        - mountPath: /var/log/openvswitch/
          name: host-var-log-ovs
        - mountPath: /var/log/ovn/
          name: host-var-log-ovs
        - mountPath: /var/run/openvswitch/
          name: host-var-run-ovs
        - mountPath: /var/run/ovn/
          name: host-var-run-ovs
        - mountPath: /ovn-cert
          name: host-ovn-cert
          readOnly: true

        resources:
          requests:
            cpu: 100m
            memory: 300Mi
        env:
        - name: OVN_DAEMONSET_VERSION
          value: "3"
        - name: OVN_LOGLEVEL_SB
          value: "{{ ovn_loglevel_sb }}"
        - name: K8S_APISERVER
          valueFrom:
            configMapKeyRef:
              name: ovn-config
              key: k8s_apiserver
        - name: OVN_KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: K8S_NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: OVN_SSL_ENABLE
          value: "{{ ovn_ssl_en }}"
        - name: OVN_SB_RAFT_ELECTION_TIMER
          value: "{{ ovn_sb_raft_election_timer }}"
        - name: OVN_SB_PORT
          value: "{{ ovn_sb_port }}"
        - name: OVN_SB_RAFT_PORT
          value: "{{ ovn_sb_raft_port }}"
      # end of container


      # ovn-dbchecker - v3
      - name: ovn-dbchecker
        image: "{{ ovn_image | default('docker.io/ovnkube/ovn-daemonset:latest') }}"
        imagePullPolicy: "{{ ovn_image_pull_policy | default('IfNotPresent') }}"
        command: ["/root/ovnkube.sh", "ovn-dbchecker"]
        securityContext:
          runAsUser: 0
          capabilities:
            add: ["NET_ADMIN"]
        terminationMessagePolicy: FallbackToLogsOnError
        volumeMounts:
        # ovn db is stored in the pod in /etc/openvswitch
        # (or in /etc/ovn if OVN from new repository is used)
        # and on the host in /var/lib/openvswitch/
        - mountPath: /etc/openvswitch/
          name: host-var-lib-ovs
        - mountPath: /etc/ovn/
          name: host-var-lib-ovs
        - mountPath: /var/log/openvswitch/
          name: host-var-log-ovs
        - mountPath: /var/log/ovn/
          name: host-var-log-ovs
        - mountPath: /var/run/openvswitch/
          name: host-var-run-ovs
        - mountPath: /var/run/ovn/
          name: host-var-run-ovs
        - mountPath: /ovn-cert
          name: host-ovn-cert
          readOnly: true

        resources:
          requests:
            cpu: 100m
            memory: 300Mi
        env:
        - name: OVN_DAEMONSET_VERSION
          value: "3"
        - name: OVNKUBE_LOGLEVEL
          value: "{{ ovn_dbchecker_loglevel }}"
        - name: OVNKUBE_LOGFILE_MAXSIZE
          value: "{{ ovnkube_logfile_maxsize }}"
        - name: OVNKUBE_LOGFILE_MAXBACKUPS
          value: "{{ ovnkube_logfile_maxbackups }}"
        - name: OVNKUBE_LOGFILE_MAXAGE
          value: "{{ ovnkube_logfile_maxage }}"
        - name: K8S_APISERVER
          valueFrom:
            configMapKeyRef:
              name: ovn-config
              key: k8s_apiserver
        - name: OVN_KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: K8S_NODE_IP
          valueFrom:
            fieldRef:
              fieldPath: status.hostIP
        - name: OVN_SSL_ENABLE
          value: "{{ ovn_ssl_en }}"
        - name: OVN_NB_RAFT_ELECTION_TIMER
          value: "{{ ovn_nb_raft_election_timer }}"
        - name: OVN_NB_PORT
          value: "{{ ovn_nb_port }}"
        - name: OVN_NB_RAFT_PORT
          value: "{{ ovn_nb_raft_port }}"
      # end of container

      volumes:
      - name: host-var-log-ovs
        hostPath:
          path: /var/log/openvswitch
      - name: host-var-lib-ovs
        hostPath:
          path: /var/lib/openvswitch
      - name: host-var-run-ovs
        hostPath:
          path: /var/run/openvswitch
      - name: host-ovn-cert
        hostPath:
          path: /etc/ovn
          type: DirectoryOrCreate
      tolerations:
      - operator: "Exists"
