mode: 0644
path: "/etc/kubernetes/static-pod-resources/keepalived/keepalived.conf.tmpl"
contents:
  inline: |
    global_defs {
        enable_script_security
        script_user root
    }

    # These are separate checks to provide the following behavior:
    # If the loadbalanced endpoint is responding then all is well regardless
    # of what the local api status is. Both checks will return success and
    # we'll have the maximum priority. This means as long as there is a node
    # with a functional loadbalancer it will get the VIP.
    # If all of the loadbalancers go down but the local api is still running,
    # the _both check will still succeed and allow any node with a functional
    # api to take the VIP. This isn't preferred because it means all api
    # traffic will go through one node, but at least it keeps the api available.
    vrrp_script chk_ocp_lb {
        script "/usr/bin/timeout 1.9 /etc/keepalived/chk_ocp_script.sh"
        interval 2
        weight 20
        rise 3
        fall 2
    }

    vrrp_script chk_ocp_both {
        script "/usr/bin/timeout 1.9 /etc/keepalived/chk_ocp_script_both.sh"
        interval 2
        # Use a smaller weight for this check so it won't trigger the move from
        # bootstrap to master by itself.
        weight 5
        rise 3
        fall 2
    }

    # TODO: Improve this check. The port is assumed to be alive.
    # Need to assess what is the ramification if the port is not there.
    vrrp_script chk_ingress {
        script "/usr/bin/timeout 0.9 /usr/bin/curl -o /dev/null -Lfs http://localhost:1936/healthz/ready"
        interval 1
        weight 50
    }

    {{`{{$nonVirtualIP := .NonVirtualIP}}`}}

    vrrp_instance {{`{{ .Cluster.Name }}`}}_API {
        state BACKUP
        interface {{`{{ .VRRPInterface }}`}}
        virtual_router_id {{`{{ .Cluster.APIVirtualRouterID }}`}}
        priority 40
        advert_int 1
        {{`{{if .EnableUnicast}}`}}
        unicast_src_ip {{`{{.NonVirtualIP}}`}}
        unicast_peer {
            {{`{{ .BootstrapIP }}`}}
            {{`{{range .LBConfig.Backends}}
            {{if ne $nonVirtualIP .Address}}{{.Address}}{{end}}
            {{end}}`}}
        }
        {{`{{end}}`}}
        authentication {
            auth_type PASS
            auth_pass {{`{{ .Cluster.Name }}`}}_api_vip
        }
        virtual_ipaddress {
            {{`{{ .Cluster.APIVIP }}`}}/{{`{{ .Cluster.VIPNetmask }}`}}
        }
        track_script {
            chk_ocp_lb
            chk_ocp_both
        }
    }

    vrrp_instance {{`{{ .Cluster.Name }}`}}_INGRESS {
        state BACKUP
        interface {{`{{ .VRRPInterface }}`}}
        virtual_router_id {{`{{ .Cluster.IngressVirtualRouterID }}`}}
        priority 40
        advert_int 1
        {{`{{if .EnableUnicast}}`}}
        unicast_src_ip {{`{{.NonVirtualIP}}`}}
        unicast_peer {
            {{`{{range .IngressConfig.Peers}}
            {{if ne $nonVirtualIP .}}{{.}}{{end}}
            {{end}}`}}
        }
        {{`{{end}}`}}
        authentication {
            auth_type PASS
            auth_pass {{`{{ .Cluster.Name }}`}}_ingress_vip
        }
        virtual_ipaddress {
            {{`{{ .Cluster.IngressVIP }}`}}/{{`{{ .Cluster.VIPNetmask }}`}}
        }
        track_script {
            chk_ingress
        }
    }
