// toURLMap converts an ingress to a map of subdomain: url-regex: gce backend. func (t *GCETranslator) toURLMap(ing *extensions.Ingress) (utils.GCEURLMap, error) { hostPathBackend := utils.GCEURLMap{} for _, rule := range ing.Spec.Rules { if rule.HTTP == nil { glog.Errorf("Ignoring non http Ingress rule") continue } pathToBackend := map[string]*compute.BackendService{} for _, p := range rule.HTTP.Paths { backend, err := t.toGCEBackend(&p.Backend, ing.Namespace) if err != nil { // If a service doesn't have a nodeport we can still forward traffic // to all other services under the assumption that the user will // modify nodeport. if _, ok := err.(errorNodePortNotFound); ok { t.recorder.Eventf(ing, api.EventTypeWarning, "Service", err.(errorNodePortNotFound).Error()) continue } // If a service doesn't have a backend, there's nothing the user // can do to correct this (the admin might've limited quota). // So keep requeuing the l7 till all backends exist. return utils.GCEURLMap{}, err } // The Ingress spec defines empty path as catch-all, so if a user // asks for a single host and multiple empty paths, all traffic is // sent to one of the last backend in the rules list. path := p.Path if path == "" { path = loadbalancers.DefaultPath } pathToBackend[path] = backend } // If multiple hostless rule sets are specified, last one wins host := rule.Host if host == "" { host = loadbalancers.DefaultHost } hostPathBackend[host] = pathToBackend } defaultBackend, _ := t.toGCEBackend(ing.Spec.Backend, ing.Namespace) hostPathBackend.PutDefaultBackend(defaultBackend) if defaultBackend != nil && ing.Spec.Backend != nil { t.recorder.Eventf(ing, api.EventTypeNormal, "GCE", fmt.Sprintf("default backend set to %v:%v", ing.Spec.Backend.ServiceName, defaultBackend.Port)) } return hostPathBackend, nil }
func TestUpdateUrlMap(t *testing.T) { um1 := utils.GCEURLMap{ "bar.example.com": { "/bar2": &compute.BackendService{SelfLink: "bar2svc"}, }, } um2 := utils.GCEURLMap{ "foo.example.com": { "/foo1": &compute.BackendService{SelfLink: "foo1svc"}, "/foo2": &compute.BackendService{SelfLink: "foo2svc"}, }, "bar.example.com": { "/bar1": &compute.BackendService{SelfLink: "bar1svc"}, }, } um2.PutDefaultBackend(&compute.BackendService{SelfLink: "default"}) lbInfo := &L7RuntimeInfo{Name: "test", AllowHTTP: true} f := NewFakeLoadBalancers(lbInfo.Name) pool := newFakeLoadBalancerPool(f, t) pool.Sync([]*L7RuntimeInfo{lbInfo}) l7, err := pool.Get(lbInfo.Name) if err != nil { t.Fatalf("%v", err) } for _, ir := range []utils.GCEURLMap{um1, um2} { if err := l7.UpdateUrlMap(ir); err != nil { t.Fatalf("%v", err) } } // The final map doesn't contain /bar2 expectedMap := map[string]utils.FakeIngressRuleValueMap{ utils.DefaultBackendKey: { utils.DefaultBackendKey: "default", }, "foo.example.com": { "/foo1": "foo1svc", "/foo2": "foo2svc", }, "bar.example.com": { "/bar1": "bar1svc", }, } f.CheckURLMap(t, l7, expectedMap) }