func (lbc *loadBalancerController) getUpstreamServers(data []interface{}) ([]*nginx.Upstream, []*nginx.Server) { upstreams := lbc.createUpstreams(data) upstreams[defUpstreamName] = lbc.getDefaultUpstream() servers := lbc.createServers(data) // default server - no servername. servers[defServerName] = &nginx.Server{ Name: defServerName, Locations: []*nginx.Location{{ Path: "/", Upstream: *lbc.getDefaultUpstream(), }, }, } for _, ingIf := range data { ing := ingIf.(*extensions.Ingress) for _, rule := range ing.Spec.Rules { if rule.IngressRuleValue.HTTP == nil { continue } server := servers[rule.Host] locations := []*nginx.Location{} for _, path := range rule.HTTP.Paths { upsName := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), path.Backend.ServiceName, path.Backend.ServicePort.IntValue()) ups := upstreams[upsName] svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName) svcObj, svcExists, err := lbc.svcLister.Store.GetByKey(svcKey) if err != nil { glog.Infof("error getting service %v from the cache: %v", svcKey, err) continue } if !svcExists { glog.Warningf("service %v does no exists", svcKey) continue } svc := svcObj.(*api.Service) for _, servicePort := range svc.Spec.Ports { if servicePort.Port == path.Backend.ServicePort.IntValue() { endps := lbc.getEndpoints(svc, servicePort.TargetPort, api.ProtocolTCP) if len(endps) == 0 { glog.Warningf("service %v does no have any active endpoints", svcKey) } ups.Backends = append(ups.Backends, endps...) break } } for _, ups := range upstreams { if upsName == ups.Name { loc := &nginx.Location{Path: path.Path} loc.Upstream = *ups locations = append(locations, loc) break } } } for _, loc := range locations { server.Locations = append(server.Locations, loc) } } } // TODO: find a way to make this more readable // The structs must be ordered to always generate the same file // if the content does not change. aUpstreams := make([]*nginx.Upstream, 0, len(upstreams)) for _, value := range upstreams { if len(value.Backends) == 0 { value.Backends = append(value.Backends, nginx.NewDefaultServer()) } sort.Sort(nginx.UpstreamServerByAddrPort(value.Backends)) aUpstreams = append(aUpstreams, value) } sort.Sort(nginx.UpstreamByNameServers(aUpstreams)) aServers := make([]*nginx.Server, 0, len(servers)) for _, value := range servers { sort.Sort(nginx.LocationByPath(value.Locations)) aServers = append(aServers, value) } sort.Sort(nginx.ServerByName(aServers)) return aUpstreams, aServers }
func (lbc *loadBalancerController) getUpstreamServers(ngxCfg config.Configuration, data []interface{}) ([]*nginx.Upstream, []*nginx.Server) { upstreams := lbc.createUpstreams(ngxCfg, data) upstreams[defUpstreamName] = lbc.getDefaultUpstream() servers := lbc.createServers(data) if _, ok := servers[defServerName]; !ok { // default server - no servername. // there is no rule with default backend servers[defServerName] = &nginx.Server{ Name: defServerName, Locations: []*nginx.Location{{ Path: rootLocation, IsDefBackend: true, Upstream: *lbc.getDefaultUpstream(), }, }, } } for _, ingIf := range data { ing := ingIf.(*extensions.Ingress) for _, rule := range ing.Spec.Rules { if rule.IngressRuleValue.HTTP == nil { continue } nginxAuth, err := auth.ParseAnnotations(lbc.client, ing, auth.DefAuthDirectory) glog.V(3).Infof("nginx auth %v", nginxAuth) if err != nil { glog.V(3).Infof("error reading authentication in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } rl, err := ratelimit.ParseAnnotations(ing) glog.V(3).Infof("nginx rate limit %v", rl) if err != nil { glog.V(3).Infof("error reading rate limit annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } secUpstream, err := secureupstream.ParseAnnotations(ing) if err != nil { glog.V(3).Infof("error reading secure upstream in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } locRew, err := rewrite.ParseAnnotations(ngxCfg, ing) if err != nil { glog.V(3).Infof("error parsing rewrite annotations for Ingress rule %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } wl, err := ipwhitelist.ParseAnnotations(ngxCfg.WhitelistSourceRange, ing) glog.V(3).Infof("nginx white list %v", wl) if err != nil { glog.V(3).Infof("error reading white list annotation in Ingress %v/%v: %v", ing.GetNamespace(), ing.GetName(), err) } host := rule.Host if host == "" { host = defServerName } server := servers[host] if server == nil { server = servers["_"] } for _, path := range rule.HTTP.Paths { upsName := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), path.Backend.ServiceName, path.Backend.ServicePort.String()) ups := upstreams[upsName] nginxPath := path.Path // if there's no path defined we assume / if nginxPath == "" { lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "Ingress rule '%v/%v' contains no path definition. Assuming /", ing.GetNamespace(), ing.GetName()) nginxPath = rootLocation } // Validate that there is no another previuous // rule for the same host and path. addLoc := true for _, loc := range server.Locations { if loc.Path == rootLocation && nginxPath == rootLocation && loc.IsDefBackend { loc.Upstream = *ups loc.Auth = *nginxAuth loc.RateLimit = *rl loc.Redirect = *locRew loc.SecureUpstream = secUpstream loc.Whitelist = *wl addLoc = false continue } if loc.Path == nginxPath { lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "Path '%v' already defined in another Ingress rule", nginxPath) addLoc = false break } } if addLoc { server.Locations = append(server.Locations, &nginx.Location{ Path: nginxPath, Upstream: *ups, Auth: *nginxAuth, RateLimit: *rl, Redirect: *locRew, SecureUpstream: secUpstream, Whitelist: *wl, }) } } } } // TODO: find a way to make this more readable // The structs must be ordered to always generate the same file // if the content does not change. aUpstreams := make([]*nginx.Upstream, 0, len(upstreams)) for _, value := range upstreams { if len(value.Backends) == 0 { glog.Warningf("upstream %v does not have any active endpoints. Using default backend", value.Name) value.Backends = append(value.Backends, nginx.NewDefaultServer()) } sort.Sort(nginx.UpstreamServerByAddrPort(value.Backends)) aUpstreams = append(aUpstreams, value) } sort.Sort(nginx.UpstreamByNameServers(aUpstreams)) aServers := make([]*nginx.Server, 0, len(servers)) for _, value := range servers { sort.Sort(nginx.LocationByPath(value.Locations)) aServers = append(aServers, value) } sort.Sort(nginx.ServerByName(aServers)) return aUpstreams, aServers }
func (lbc *loadBalancerController) getUpstreamServers(data []interface{}) ([]*nginx.Upstream, []*nginx.Server) { upstreams := lbc.createUpstreams(data) upstreams[defUpstreamName] = lbc.getDefaultUpstream() servers := lbc.createServers(data) if _, ok := servers[defServerName]; !ok { // default server - no servername. // there is no rule with default backend servers[defServerName] = &nginx.Server{ Name: defServerName, Locations: []*nginx.Location{{ Path: rootLocation, IsDefBackend: true, Upstream: *lbc.getDefaultUpstream(), }, }, } } for _, ingIf := range data { ing := ingIf.(*extensions.Ingress) for _, rule := range ing.Spec.Rules { if rule.IngressRuleValue.HTTP == nil { continue } host := rule.Host if host == "" { host = defServerName } server := servers[host] if server == nil { server = servers["_"] } for _, path := range rule.HTTP.Paths { upsName := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), path.Backend.ServiceName, path.Backend.ServicePort.String()) ups := upstreams[upsName] nginxPath := path.Path // if there's no path defined we assume / if nginxPath == "" { lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "Ingress rule '%v/%v' contains no path definition. Assuming /", ing.GetNamespace(), ing.GetName()) nginxPath = rootLocation } // Validate that there is no another previuous // rule for the same host and path. addLoc := true for _, loc := range server.Locations { if loc.Path == rootLocation && nginxPath == rootLocation && loc.IsDefBackend { loc.Upstream = *ups addLoc = false continue } if loc.Path == nginxPath { lbc.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "Path '%v' already defined in another Ingress rule", nginxPath) addLoc = false break } } if addLoc { server.Locations = append(server.Locations, &nginx.Location{ Path: nginxPath, Upstream: *ups, }) } } } } // TODO: find a way to make this more readable // The structs must be ordered to always generate the same file // if the content does not change. aUpstreams := make([]*nginx.Upstream, 0, len(upstreams)) for _, value := range upstreams { if len(value.Backends) == 0 { glog.Warningf("upstream %v does no have any active endpoints. Using default backend", value.Name) value.Backends = append(value.Backends, nginx.NewDefaultServer()) } sort.Sort(nginx.UpstreamServerByAddrPort(value.Backends)) aUpstreams = append(aUpstreams, value) } sort.Sort(nginx.UpstreamByNameServers(aUpstreams)) aServers := make([]*nginx.Server, 0, len(servers)) for _, value := range servers { sort.Sort(nginx.LocationByPath(value.Locations)) aServers = append(aServers, value) } sort.Sort(nginx.ServerByName(aServers)) return aUpstreams, aServers }