// getServiceEnvVarMap makes a map[string]string of env vars for services a // pod in namespace ns should see. func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) { var ( serviceMap = make(map[string]*api.Service) m = make(map[string]string) ) // Get all service resources from the master (via a cache), // and populate them into service environment variables. if kl.serviceLister == nil { // Kubelets without masters (e.g. plain GCE ContainerVM) don't set env vars. return m, nil } services, err := kl.serviceLister.List(labels.Everything()) if err != nil { return m, fmt.Errorf("failed to list services when setting up env vars.") } // project the services in namespace ns onto the master services for i := range services { service := services[i] // ignore services where ClusterIP is "None" or empty if !api.IsServiceIPSet(service) { continue } serviceName := service.Name switch service.Namespace { // for the case whether the master service namespace is the namespace the pod // is in, the pod should receive all the services in the namespace. // // ordering of the case clauses below enforces this case ns: serviceMap[serviceName] = service case kl.masterServiceNamespace: if masterServices.Has(serviceName) { if _, exists := serviceMap[serviceName]; !exists { serviceMap[serviceName] = service } } } } mappedServices := []*api.Service{} for key := range serviceMap { mappedServices = append(mappedServices, serviceMap[key]) } for _, e := range envvars.FromServices(mappedServices) { m[e.Name] = e.Value } return m, nil }
func TestFromServices(t *testing.T) { sl := []*v1.Service{ { ObjectMeta: v1.ObjectMeta{Name: "foo-bar"}, Spec: v1.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "1.2.3.4", Ports: []v1.ServicePort{ {Port: 8080, Protocol: "TCP"}, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "abc-123"}, Spec: v1.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "5.6.7.8", Ports: []v1.ServicePort{ {Name: "u-d-p", Port: 8081, Protocol: "UDP"}, {Name: "t-c-p", Port: 8081, Protocol: "TCP"}, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "q-u-u-x"}, Spec: v1.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "9.8.7.6", Ports: []v1.ServicePort{ {Port: 8082, Protocol: "TCP"}, {Name: "8083", Port: 8083, Protocol: "TCP"}, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "svrc-clusterip-none"}, Spec: v1.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "None", Ports: []v1.ServicePort{ {Port: 8082, Protocol: "TCP"}, }, }, }, { ObjectMeta: v1.ObjectMeta{Name: "svrc-clusterip-empty"}, Spec: v1.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, ClusterIP: "", Ports: []v1.ServicePort{ {Port: 8082, Protocol: "TCP"}, }, }, }, } vars := envvars.FromServices(sl) expected := []v1.EnvVar{ {Name: "FOO_BAR_SERVICE_HOST", Value: "1.2.3.4"}, {Name: "FOO_BAR_SERVICE_PORT", Value: "8080"}, {Name: "FOO_BAR_PORT", Value: "tcp://1.2.3.4:8080"}, {Name: "FOO_BAR_PORT_8080_TCP", Value: "tcp://1.2.3.4:8080"}, {Name: "FOO_BAR_PORT_8080_TCP_PROTO", Value: "tcp"}, {Name: "FOO_BAR_PORT_8080_TCP_PORT", Value: "8080"}, {Name: "FOO_BAR_PORT_8080_TCP_ADDR", Value: "1.2.3.4"}, {Name: "ABC_123_SERVICE_HOST", Value: "5.6.7.8"}, {Name: "ABC_123_SERVICE_PORT", Value: "8081"}, {Name: "ABC_123_SERVICE_PORT_U_D_P", Value: "8081"}, {Name: "ABC_123_SERVICE_PORT_T_C_P", Value: "8081"}, {Name: "ABC_123_PORT", Value: "udp://5.6.7.8:8081"}, {Name: "ABC_123_PORT_8081_UDP", Value: "udp://5.6.7.8:8081"}, {Name: "ABC_123_PORT_8081_UDP_PROTO", Value: "udp"}, {Name: "ABC_123_PORT_8081_UDP_PORT", Value: "8081"}, {Name: "ABC_123_PORT_8081_UDP_ADDR", Value: "5.6.7.8"}, {Name: "ABC_123_PORT_8081_TCP", Value: "tcp://5.6.7.8:8081"}, {Name: "ABC_123_PORT_8081_TCP_PROTO", Value: "tcp"}, {Name: "ABC_123_PORT_8081_TCP_PORT", Value: "8081"}, {Name: "ABC_123_PORT_8081_TCP_ADDR", Value: "5.6.7.8"}, {Name: "Q_U_U_X_SERVICE_HOST", Value: "9.8.7.6"}, {Name: "Q_U_U_X_SERVICE_PORT", Value: "8082"}, {Name: "Q_U_U_X_SERVICE_PORT_8083", Value: "8083"}, {Name: "Q_U_U_X_PORT", Value: "tcp://9.8.7.6:8082"}, {Name: "Q_U_U_X_PORT_8082_TCP", Value: "tcp://9.8.7.6:8082"}, {Name: "Q_U_U_X_PORT_8082_TCP_PROTO", Value: "tcp"}, {Name: "Q_U_U_X_PORT_8082_TCP_PORT", Value: "8082"}, {Name: "Q_U_U_X_PORT_8082_TCP_ADDR", Value: "9.8.7.6"}, {Name: "Q_U_U_X_PORT_8083_TCP", Value: "tcp://9.8.7.6:8083"}, {Name: "Q_U_U_X_PORT_8083_TCP_PROTO", Value: "tcp"}, {Name: "Q_U_U_X_PORT_8083_TCP_PORT", Value: "8083"}, {Name: "Q_U_U_X_PORT_8083_TCP_ADDR", Value: "9.8.7.6"}, } if len(vars) != len(expected) { t.Errorf("Expected %d env vars, got: %+v", len(expected), vars) return } for i := range expected { if !reflect.DeepEqual(vars[i], expected[i]) { t.Errorf("expected %#v, got %#v", vars[i], expected[i]) } } }