func()

in pkg/appgw/health_probes.go [78:218]


func (c *appGwConfigBuilder) generateHealthProbe(backendID backendIdentifier) *n.ApplicationGatewayProbe {
	// TODO(draychev): remove GetService
	service := c.k8sContext.GetService(backendID.serviceKey())
	if service == nil || backendID.Path == nil {
		return nil
	}
	probe := defaultProbe(c.appGwIdentifier, n.ApplicationGatewayProtocolHTTP)
	probe.Name = to.StringPtr(generateProbeName(backendID.Path.Backend.Service.Name, serviceBackendPortToStr(backendID.Path.Backend.Service.Port), backendID.Ingress))
	probe.ID = to.StringPtr(c.appGwIdentifier.probeID(*probe.Name))

	// set defaults
	probe.Match = &n.ApplicationGatewayProbeHealthResponseMatch{}
	probe.PickHostNameFromBackendHTTPSettings = to.BoolPtr(false)
	probe.MinServers = to.Int32Ptr(0)

	listenerID := generateListenerID(backendID.Ingress, backendID.Rule, n.ApplicationGatewayProtocolHTTP, nil, false)
	hostName := listenerID.getHostNameForProbes()
	if hostName != nil {
		probe.Host = hostName
	}

	if hostName, err := annotations.BackendHostName(backendID.Ingress); err == nil {
		probe.Host = to.StringPtr(hostName)
	}

	pathPrefix, err := annotations.BackendPathPrefix(backendID.Ingress)
	if err == nil {
		probe.Path = to.StringPtr(pathPrefix)
	} else if backendID.Path != nil && len(backendID.Path.Path) != 0 {
		probe.Path = to.StringPtr(backendID.Path.Path)
	}

	// check if backend is using port 443
	if backendID.Backend.Service != nil {
		if serviceBackendPortToStr(backendID.Backend.Service.Port) == "443" {
			probe.Protocol = n.ApplicationGatewayProtocolHTTPS
		} else if port, err := c.resolveBackendPort(backendID); err == nil && port == Port(443) {
			probe.Protocol = n.ApplicationGatewayProtocolHTTPS
		}
	}

	k8sProbeForServiceContainer := c.getProbeForServiceContainer(service, backendID)
	if k8sProbeForServiceContainer != nil {
		if len(k8sProbeForServiceContainer.HTTPGet.Host) != 0 {
			probe.Host = to.StringPtr(k8sProbeForServiceContainer.HTTPGet.Host)
		}
		if len(k8sProbeForServiceContainer.HTTPGet.Path) != 0 {
			probe.Path = to.StringPtr(k8sProbeForServiceContainer.HTTPGet.Path)
		}
		if len(k8sProbeForServiceContainer.HTTPGet.Port.String()) != 0 {
			probe.Port = to.Int32Ptr(k8sProbeForServiceContainer.HTTPGet.Port.IntVal)
		}
		if k8sProbeForServiceContainer.HTTPGet.Scheme == v1.URISchemeHTTPS {
			probe.Protocol = n.ApplicationGatewayProtocolHTTPS
		}
		// httpGet schema is default to Http if not specified, double check with the port in case for Https
		if k8sProbeForServiceContainer.HTTPGet.Scheme == v1.URISchemeHTTP {
			if k8sProbeForServiceContainer.HTTPGet.Port.IntVal == 443 {
				probe.Protocol = n.ApplicationGatewayProtocolHTTPS
			} else {
				probe.Protocol = n.ApplicationGatewayProtocolHTTP
			}
		}
		if k8sProbeForServiceContainer.PeriodSeconds != 0 {
			probe.Interval = to.Int32Ptr(k8sProbeForServiceContainer.PeriodSeconds)
		}
		if k8sProbeForServiceContainer.TimeoutSeconds != 0 {
			probe.Timeout = to.Int32Ptr(k8sProbeForServiceContainer.TimeoutSeconds)
		}
		if k8sProbeForServiceContainer.FailureThreshold != 0 {
			// UnhealthyThreshold must be in range of 0 - 20, otherwise Application Gateway will not
			// accept the configuration and all new pods will not be configured.
			if k8sProbeForServiceContainer.FailureThreshold > 20 {
				probe.UnhealthyThreshold = to.Int32Ptr(20)
			} else {
				probe.UnhealthyThreshold = to.Int32Ptr(k8sProbeForServiceContainer.FailureThreshold)
			}
		}
	}

	// backend protocol must match http settings protocol
	backendProtocol, err := annotations.BackendProtocol(backendID.Ingress)
	if err == nil && backendProtocol == annotations.HTTPS {
		probe.Protocol = n.ApplicationGatewayProtocolHTTPS
	} else if err == nil && backendProtocol == annotations.HTTP {
		probe.Protocol = n.ApplicationGatewayProtocolHTTP
	}

	// override healthcheck probe host with host defined in annotation if exists
	probeHost, err := annotations.HealthProbeHostName(backendID.Ingress)
	if err == nil && probeHost != "" {
		probe.Host = to.StringPtr(probeHost)
	}

	// override healthcheck probe target port with port defined in annotation if exists
	probePort, err := annotations.HealthProbePort(backendID.Ingress)
	if err == nil && probePort > 0 && probePort < 65536 {
		probe.Port = to.Int32Ptr(probePort)
	}

	// override healthcheck probe path with path defined in annotation if exists
	probePath, err := annotations.HealthProbePath(backendID.Ingress)
	if err == nil && probePath != "" {
		probe.Path = to.StringPtr(probePath)
	}

	if probe.Path != nil {
		probe.Path = to.StringPtr(strings.TrimRight(*probe.Path, "*"))
	}

	// override healthcheck probe match status codes with ones defined in annotation if exists
	probeStatuses, err := annotations.HealthProbeStatusCodes(backendID.Ingress)
	if err == nil && len(probeStatuses) > 0 {
		probe.Match.StatusCodes = &probeStatuses
	}

	// override healthcheck probe interval with value defined in annotation if exists
	probeInterval, err := annotations.HealthProbeInterval(backendID.Ingress)
	if err == nil && probeInterval > 0 {
		probe.Interval = to.Int32Ptr(probeInterval)
	}

	// override healthcheck probe timeout with value defined in annotation if exists
	probeTimeout, err := annotations.HealthProbeTimeout(backendID.Ingress)
	if err == nil && probeTimeout > 0 {
		probe.Timeout = to.Int32Ptr(probeTimeout)
	}

	// override healthcheck probe threshold with value defined in annotation if exists
	probeThreshold, err := annotations.HealthProbeUnhealthyThreshold(backendID.Ingress)
	if err == nil && probeThreshold > 0 {
		probe.UnhealthyThreshold = to.Int32Ptr(probeThreshold)
	}

	// For V1 gateway, port property is not supported
	if c.appGw.Sku.Tier == n.ApplicationGatewayTierStandard || c.appGw.Sku.Tier == n.ApplicationGatewayTierWAF {
		probe.Port = nil
	}

	return &probe
}