pkg/brownfield/listeners.go (140 lines of code) (raw):

// ------------------------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. // -------------------------------------------------------------------------------------------- package brownfield import ( "math" "strings" n "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2021-03-01/network" "k8s.io/klog/v2" "github.com/Azure/application-gateway-kubernetes-ingress/pkg/utils" ) const ( // MaxAllowedHostNames the maximum number of HostNames allowed for listener. MaxAllowedHostNames int = 5 ) type listenersByName map[listenerName]n.ApplicationGatewayHTTPListener // GetBlacklistedListeners filters the given list of health probes to the list Probes that AGIC is allowed to manage. func (er ExistingResources) GetBlacklistedListeners() ([]n.ApplicationGatewayHTTPListener, []n.ApplicationGatewayHTTPListener) { blacklistedListenersSet := er.getBlacklistedListenersSet() var blacklisted, nonBlacklisted []n.ApplicationGatewayHTTPListener for _, listener := range er.Listeners { listenerNm := listenerName(*listener.Name) if _, exists := blacklistedListenersSet[listenerNm]; exists { klog.V(3).Infof("[brownfield] Listener %s is blacklisted", listenerNm) blacklisted = append(blacklisted, listener) continue } klog.V(3).Infof("[brownfield] Listener %s is not blacklisted", listenerNm) nonBlacklisted = append(nonBlacklisted, listener) } return blacklisted, nonBlacklisted } type uniqueListenerConfig struct { HostNames [MaxAllowedHostNames]string Protocol n.ApplicationGatewayProtocol FrontendPortID string FrontendIPConfiguration string } func (config *uniqueListenerConfig) setHostNames(hostNames []string) { hostnameCount := int(math.Min(float64(len(hostNames)), float64(MaxAllowedHostNames))) for i := 0; i < hostnameCount; i++ { config.HostNames[i] = hostNames[i] } } // MergeListeners merges list of lists of listeners into a single list, maintaining uniqueness. func MergeListeners(listenerBuckets ...[]n.ApplicationGatewayHTTPListener) []n.ApplicationGatewayHTTPListener { uniq := make(map[uniqueListenerConfig]n.ApplicationGatewayHTTPListener) for _, bucket := range listenerBuckets { for _, listener := range bucket { listenerConfig := uniqueListenerConfig{ Protocol: listener.Protocol, } if listener.HostName != nil { listenerConfig.setHostNames([]string{*listener.HostName}) } if listener.HostNames != nil && len(*listener.HostNames) > 0 { listenerConfig.setHostNames(*listener.HostNames) } if listener.FrontendIPConfiguration != nil && listener.FrontendIPConfiguration.ID != nil { listenerConfig.FrontendIPConfiguration = *listener.FrontendIPConfiguration.ID } if listener.FrontendPort != nil && listener.FrontendPort.ID != nil { listenerConfig.FrontendPortID = *listener.FrontendPort.ID } if _, exists := uniq[listenerConfig]; !exists { uniq[listenerConfig] = listener } } } var merged []n.ApplicationGatewayHTTPListener for _, listener := range uniq { merged = append(merged, listener) } return merged } // LogListeners emits a few log lines detailing what Listeners are created, blacklisted, and removed from ARM. func LogListeners(existingBlacklisted []n.ApplicationGatewayHTTPListener, existingNonBlacklisted []n.ApplicationGatewayHTTPListener, managedListeners []n.ApplicationGatewayHTTPListener) { var garbage []n.ApplicationGatewayHTTPListener blacklistedSet := indexListenersByName(existingBlacklisted) managedSet := indexListenersByName(managedListeners) for listenerName, listener := range indexListenersByName(existingNonBlacklisted) { _, existsInBlacklist := blacklistedSet[listenerName] _, existsInNewListeners := managedSet[listenerName] if !existsInBlacklist && !existsInNewListeners { garbage = append(garbage, listener) } } klog.V(3).Info("[brownfield] Listeners AGIC created: ", getListenerNames(managedListeners)) klog.V(3).Info("[brownfield] Existing Blacklisted Listeners AGIC will retain: ", getListenerNames(existingBlacklisted)) klog.V(3).Info("[brownfield] Existing Listeners AGIC will remove: ", getListenerNames(garbage)) } func getListenerNames(listeners []n.ApplicationGatewayHTTPListener) string { var names []string for _, p := range listeners { names = append(names, *p.Name) } if len(names) == 0 { return "n/a" } return strings.Join(names, ", ") } func indexListenersByName(listeners []n.ApplicationGatewayHTTPListener) listenersByName { indexed := make(listenersByName) for _, listener := range listeners { indexed[listenerName(*listener.Name)] = listener } return indexed } // getListenersByName indexes listeners by their name func (er *ExistingResources) getListenersByName() listenersByName { if er.listenersByName != nil { return er.listenersByName } listenersByName := make(listenersByName) for _, listener := range er.Listeners { listenersByName[listenerName(listenerName(*listener.Name))] = listener } er.listenersByName = listenersByName return listenersByName } func (er ExistingResources) getBlacklistedListenersSet() map[listenerName]interface{} { // Determine the list of prohibited listeners from the HostNames blacklistedListenersSet := make(map[listenerName]interface{}) prohibitedHostNames := er.getProhibitedHostNames() for _, listener := range er.Listeners { if listener.HostName != nil { if _, exists := prohibitedHostNames[*listener.HostName]; exists { blacklistedListenersSet[listenerName(*listener.Name)] = nil continue } } if listener.HostNames != nil && len(*listener.HostNames) > 0 { for _, hostName := range *listener.HostNames { if _, exists := prohibitedHostNames[hostName]; exists { blacklistedListenersSet[listenerName(*listener.Name)] = nil continue } } } } // Augment the list of prohibited listeners by looking at the rules blacklistedRoutingRules, _ := er.GetBlacklistedRoutingRules() for _, rule := range blacklistedRoutingRules { if rule.HTTPListener != nil && rule.HTTPListener.ID != nil { listenerName := listenerName(utils.GetLastChunkOfSlashed(*rule.HTTPListener.ID)) blacklistedListenersSet[listenerName] = nil } } return blacklistedListenersSet }