func (l *loadBalancer) Owner() string {
	if l.shared {
		return ""
	}
	for _, ingresses := range l.ingresses {
		for _, ingress := range ingresses {
			return fmt.Sprintf("%s/%s", ingress.Namespace, ingress.Name)
		}
	}
	return ""
}
Owner returns the ingress resource owning the load balancer. If there are no
owners it will return an empty string meaning the load balancer is shared
between multiple ingresses.
package main
import (
	"context"
	"math"
	"reflect"
	"sort"
	"time"
	"fmt"
	"runtime/debug"
	"strings"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/cloudformation"
	log "github.com/sirupsen/logrus"
	"github.com/zalando-incubator/kube-ingress-aws-controller/aws"
	"github.com/zalando-incubator/kube-ingress-aws-controller/certs"
	"github.com/zalando-incubator/kube-ingress-aws-controller/kubernetes"
	"github.com/zalando-incubator/kube-ingress-aws-controller/problem"
)
type loadBalancer struct {
	ingresses                    map[string][]*kubernetes.Ingress
	scheme                       string
	stack                        *aws.Stack
	existingStackCertificateARNs map[string]time.Time
	shared                       bool
	http2                        bool
	clusterLocal                 bool
	securityGroup                string
	sslPolicy                    string
	ipAddressType                string
	wafWebACLID                  string
	certTTL                      time.Duration
	cwAlarms                     aws.CloudWatchAlarmList
	loadBalancerType             string
}
const (
	ready int = iota
	update
	missing
	delete
)
const (
	maxTargetGroupSupported = 1000
)
func (l *loadBalancer) Status() int {
	if l.clusterLocal {
		return ready
	}
	if l.stack.ShouldDelete() {
		return delete
	}
	if len(l.ingresses) != 0 && l.stack == nil {
		return missing
	}
	if firstRun || !l.inSync() && l.stack.IsComplete() {
		return update
	}
	return ready
}
func (l *loadBalancer) inSync() bool {
	return reflect.DeepEqual(l.CertificateARNs(), l.stack.CertificateARNs) &&
		l.stack.CWAlarmConfigHash == l.cwAlarms.Hash() &&
		l.wafWebACLID == l.stack.WAFWebACLID
}
func (l *loadBalancer) addIngress(certificateARNs []string, ingress *kubernetes.Ingress, maxCerts int) bool {
	if ingress.ClusterLocal {
		if ingresses, ok := l.ingresses[kubernetes.DefaultClusterLocalDomain]; ok {
			l.ingresses[kubernetes.DefaultClusterLocalDomain] = append(ingresses, ingress)
		} else {
			l.ingresses[kubernetes.DefaultClusterLocalDomain] = []*kubernetes.Ingress{ingress}
		}
		return true
	}
	if l.ipAddressType != ingress.IPAddressType ||
		l.scheme != ingress.Scheme ||
		l.securityGroup != ingress.SecurityGroup ||
		l.sslPolicy != ingress.SSLPolicy ||
		l.loadBalancerType != ingress.LoadBalancerType ||
		l.http2 != ingress.HTTP2 ||
		l.wafWebACLID != ingress.WAFWebACLID {
		return false
	}
	resourceName := fmt.Sprintf("%s/%s", ingress.Namespace, ingress.Name)
	owner := ""
	if l.stack != nil {
		owner = l.stack.OwnerIngress
	}
	if owner != "" && resourceName != owner {
		return false
	}
	if !ingress.Shared && resourceName != owner {
		return false
	}
	newCerts := 0
	for _, certificateARN := range certificateARNs {
		if _, ok := l.ingresses[certificateARN]; ok {
			continue
		}
		newCerts++
	}
	if len(l.ingresses)+newCerts > maxCerts {
		return false
	}
	for _, certificateARN := range certificateARNs {
		l.ingresses[certificateARN] = append(l.ingresses[certificateARN], ingress)
	}
	l.shared = ingress.Shared
	return true
}
func (l *loadBalancer) CertificateARNs() map[string]time.Time {
	certificates := make(map[string]time.Time, len(l.ingresses))
	for arn, ingresses := range l.ingresses {
		if len(ingresses) > 0 {
			certificates[arn] = time.Time{}
		}
	}
	for arn, ttl := range l.existingStackCertificateARNs {
		if _, ok := certificates[arn]; !ok {
			if ttl.IsZero() {
				certificates[arn] = time.Now().UTC().Add(l.certTTL)
			} else if ttl.After(time.Now().UTC()) {
				certificates[arn] = ttl
			}
		}
	}
	return certificates
}