Esempio n. 1
0
func (registry *Registry) WatchServices(receiver chan<- *osdnapi.ServiceEvent, ready chan<- bool, start <-chan string, stop <-chan bool) error {
	eventQueue, startVersion := registry.createAndRunEventQueue("Service", ready, start)

	checkCondition := true
	for {
		eventType, obj, err := getEvent(eventQueue, startVersion, &checkCondition)
		if err != nil {
			return err
		}
		kServ := obj.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(kServ) {
			continue
		}

		switch eventType {
		case watch.Added:
			oServ := newSDNService(kServ)
			receiver <- &osdnapi.ServiceEvent{Type: osdnapi.Added, Service: oServ}
		case watch.Deleted:
			oServ := newSDNService(kServ)
			receiver <- &osdnapi.ServiceEvent{Type: osdnapi.Deleted, Service: oServ}
		case watch.Modified:
			oServ := newSDNService(kServ)
			receiver <- &osdnapi.ServiceEvent{Type: osdnapi.Modified, Service: oServ}
		}
	}
}
Esempio n. 2
0
func (rs *REST) Delete(ctx api.Context, id string) (runtime.Object, error) {
	service, err := rs.registry.GetService(ctx, id)
	if err != nil {
		return nil, err
	}

	err = rs.registry.DeleteService(ctx, id)
	if err != nil {
		return nil, err
	}

	if api.IsServiceIPSet(service) {
		rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
	}

	for _, nodePort := range CollectServiceNodePorts(service) {
		err := rs.serviceNodePorts.Release(nodePort)
		if err != nil {
			// these should be caught by an eventual reconciliation / restart
			glog.Errorf("Error releasing service %s node port %d: %v", service.Name, nodePort, err)
		}
	}

	return &api.Status{Status: api.StatusSuccess}, nil
}
Esempio n. 3
0
func (oi *OsdnRegistryInterface) WatchServices(receiver chan<- *osdnapi.ServiceEvent, ready chan<- bool, start <-chan string, stop <-chan bool) error {
	eventQueue, startVersion := oi.createAndRunEventQueue("Service", ready, start)

	checkCondition := true
	for {
		eventType, obj, err := getEvent(eventQueue, startVersion, &checkCondition)
		if err != nil {
			return err
		}
		kServ := obj.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(kServ) {
			continue
		}

		switch eventType {
		case watch.Added:
			for _, port := range kServ.Spec.Ports {
				oServ := newSDNService(kServ, port)
				receiver <- &osdnapi.ServiceEvent{Type: osdnapi.Added, Service: oServ}
			}
		case watch.Deleted:
			for _, port := range kServ.Spec.Ports {
				oServ := newSDNService(kServ, port)
				receiver <- &osdnapi.ServiceEvent{Type: osdnapi.Deleted, Service: oServ}
			}
		case watch.Modified:
			// Ignore, we don't need to update SDN in case of service updates
		}
	}
}
Esempio n. 4
0
// FromServices builds environment variables that a container is started with,
// which tell the container where to find the services it may need, which are
// provided as an argument.
func FromServices(services *api.ServiceList) []api.EnvVar {
	var result []api.EnvVar
	for i := range services.Items {
		service := &services.Items[i]

		// ignore services where ClusterIP is "None" or empty
		// the services passed to this method should be pre-filtered
		// only services that have the cluster IP set should be included here
		if !api.IsServiceIPSet(service) {
			continue
		}

		// Host
		name := makeEnvVariableName(service.Name) + "_SERVICE_HOST"
		result = append(result, api.EnvVar{Name: name, Value: service.Spec.ClusterIP})
		// First port - give it the backwards-compatible name
		name = makeEnvVariableName(service.Name) + "_SERVICE_PORT"
		result = append(result, api.EnvVar{Name: name, Value: strconv.Itoa(service.Spec.Ports[0].Port)})
		// All named ports (only the first may be unnamed, checked in validation)
		for i := range service.Spec.Ports {
			sp := &service.Spec.Ports[i]
			if sp.Name != "" {
				pn := name + "_" + makeEnvVariableName(sp.Name)
				result = append(result, api.EnvVar{Name: pn, Value: strconv.Itoa(sp.Port)})
			}
		}
		// Docker-compatible vars.
		result = append(result, makeLinkVariables(service)...)
	}
	return result
}
Esempio n. 5
0
func (rs *REST) Delete(ctx api.Context, id string) (runtime.Object, error) {
	service, err := rs.registry.GetService(ctx, id)
	if err != nil {
		return nil, err
	}

	err = rs.registry.DeleteService(ctx, id)
	if err != nil {
		return nil, err
	}

	// TODO: can leave dangling endpoints, and potentially return incorrect
	// endpoints if a new service is created with the same name
	err = rs.endpoints.DeleteEndpoints(ctx, id)
	if err != nil && !errors.IsNotFound(err) {
		return nil, err
	}

	if api.IsServiceIPSet(service) {
		rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
	}

	for _, nodePort := range CollectServiceNodePorts(service) {
		err := rs.serviceNodePorts.Release(nodePort)
		if err != nil {
			// these should be caught by an eventual reconciliation / restart
			glog.Errorf("Error releasing service %s node port %d: %v", service.Name, nodePort, err)
		}
	}

	return &unversioned.Status{Status: unversioned.StatusSuccess}, nil
}
Esempio n. 6
0
func (ks *kube2sky) addDNS(subdomain string, service *kapi.Service, isNewStyleFormat bool) error {
	if len(service.Spec.Ports) == 0 {
		glog.Fatalf("unexpected service with no ports: %v", service)
	}
	// if ClusterIP is not set, a DNS entry should not be created
	if !kapi.IsServiceIPSet(service) {
		return ks.newHeadlessService(subdomain, service, isNewStyleFormat)
	}
	return ks.generateRecordsForPortalService(subdomain, service, isNewStyleFormat)
}
Esempio n. 7
0
func registerable(s *api.Service, sl ServiceSelector) bool {
	for k, v := range sl.fixNamespace() {
		if sv, ok := s.Labels[k]; !ok || sv != v {
			if sv, ok := s.Annotations[k]; !ok || sv != v {
				return false
			}
		}
	}
	return api.IsServiceIPSet(s)
}
Esempio n. 8
0
func (ks *kube2sky) addDNS(subdomain string, service *kapi.Service) error {
	// if ClusterIP is not set, a DNS entry should not be created
	if !kapi.IsServiceIPSet(service) {
		return ks.newHeadlessService(subdomain, service)
	}
	if len(service.Spec.Ports) == 0 {
		glog.Info("Unexpected service with no ports, this should not have happend: %v", service)
	}
	return ks.generateRecordsForPortalService(subdomain, service)
}
Esempio n. 9
0
func (ks *kube2dnsimple) addDNS(service *kapi.Service) error {
	if len(service.Spec.Ports) == 0 {
		glog.Fatalf("unexpected service with no ports: %v", service)
	}

	if !kapi.IsServiceIPSet(service) {
		return nil
	}

	return ks.generateRecordsForPortalService(service)
}
Esempio n. 10
0
File: dns.go Progetto: 40a/bootkube
func (kd *KubeDNS) addDNSUsingEndpoints(e *kapi.Endpoints) error {
	svc, err := kd.getServiceFromEndpoints(e)
	if err != nil {
		return err
	}
	if svc == nil || kapi.IsServiceIPSet(svc) {
		// No headless service found corresponding to endpoints object.
		return nil
	}
	return kd.generateRecordsForHeadlessService(e, svc)
}
Esempio n. 11
0
func (k2c *Kube2Consul) newService(obj interface{}) {
	if svc, ok := assertIsService(obj); ok {
		glog.Infof("Add/Updated for service %q", svc.Name)
		if !kapi.IsServiceIPSet(svc) {
			glog.Info("start to register service into Consul.")
			k2c.newHeadlessService(svc)
		} else {
			glog.Errorf("service %q in namespace %q is none headless service, skip it.", svc.Name, svc.Namespace)
		}
	}
}
Esempio n. 12
0
func (ks *kube2consul) createDNS(record string, service *kapi.Service, node *nodeInformation) error {
	if strings.Contains(record, ".") {
		glog.Infof("Service names containing '.' are not supported: %s\n", service.Name)
		return nil
	}

	// if ClusterIP is not set, do not create a DNS records
	if !kapi.IsServiceIPSet(service) {
		glog.Infof("Skipping dns record for headless service: %s\n", service.Name)
		return nil
	}

	//Currently this is only for NodePorts.
	if service.Spec.Type != kapi.ServiceTypeNodePort {
		glog.V(3).Infof("Skipping non-NodePort service: %s\n", service.Name)
		return nil
	}

	for i := range service.Spec.Ports {
		newId := node.name + record + service.Spec.Ports[i].Name
		var asrName string

		//If the port has a name. Use that.
		if len(service.Spec.Ports[i].Name) > 0 {
			asrName = record + "-" + service.Spec.Ports[i].Name
		} else if len(service.Spec.Ports) == 1 { //TODO: Pull out logic later
			asrName = record
		} else {
			asrName = record + "-" + strconv.Itoa(service.Spec.Ports[i].Port)
		}

		asr := &consulapi.AgentServiceRegistration{
			ID:      newId,
			Name:    asrName,
			Address: node.address,
			Port:    service.Spec.Ports[i].NodePort,
			Tags:    []string{"Kube"},
		}

		if Contains(node.ids[record], newId) == false {
			glog.Infof("Setting DNS record: %v -> %v:%d\n", asr.Name, asr.Address, asr.Port)

			if ks.consulClient != nil {
				if err := ks.consulClient.Agent().ServiceRegister(asr); err != nil {
					return err
				}
			}

			node.ids[record] = append(node.ids[record], newId)
		}
	}
	return nil
}
Esempio n. 13
0
// 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
}
Esempio n. 14
0
func (rly *relay) AddService(obj interface{}) {
	log.WithField("service", obj).Debug("Attempting to add service")

	if s, ok := obj.(*kubeAPI.Service); ok {
		serviceID := vulcandID(s)
		if s.Spec.Type != kubeAPI.ServiceTypeClusterIP || kubeAPI.IsServiceIPSet(s) {
			log.WithField("serviceID", serviceID).Info("Not adding service")
			return
		}

		rly.handleAddService(s)
	}
}
Esempio n. 15
0
File: dns.go Progetto: 40a/bootkube
func (kd *KubeDNS) newService(obj interface{}) {
	if service, ok := assertIsService(obj); ok {
		// if ClusterIP is not set, a DNS entry should not be created
		if !kapi.IsServiceIPSet(service) {
			kd.newHeadlessService(service)
			return
		}
		if len(service.Spec.Ports) == 0 {
			glog.Warning("Unexpected service with no ports, this should not have happend: %v", service)
		}
		kd.newPortalService(service)
	}
}
Esempio n. 16
0
func (node *OsdnNode) watchServices() {
	services := make(map[string]*kapi.Service)
	eventQueue := node.registry.RunEventQueue(Services)

	for {
		eventType, obj, err := eventQueue.Pop()
		if err != nil {
			utilruntime.HandleError(fmt.Errorf("EventQueue failed for services: %v", err))
			return
		}
		serv := obj.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(serv) {
			continue
		}

		log.V(5).Infof("Watch %s event for Service %q", strings.Title(string(eventType)), serv.ObjectMeta.Name)
		switch eventType {
		case watch.Added, watch.Modified:
			oldsvc, exists := services[string(serv.UID)]
			if exists {
				if !isServiceChanged(oldsvc, serv) {
					continue
				}
				if err = node.DeleteServiceRules(oldsvc); err != nil {
					log.Error(err)
				}
			}

			var netid uint32
			netid, err = node.vnids.WaitAndGetVNID(serv.Namespace)
			if err != nil {
				log.Errorf("Skipped adding service rules for serviceEvent: %v, Error: %v", eventType, err)
				continue
			}

			if err = node.AddServiceRules(serv, netid); err != nil {
				log.Error(err)
				continue
			}
			services[string(serv.UID)] = serv
		case watch.Deleted:
			delete(services, string(serv.UID))

			if err = node.DeleteServiceRules(serv); err != nil {
				log.Error(err)
			}
		}
	}
}
Esempio n. 17
0
func (kd *KubeDNS) removeService(obj interface{}) {
	if s, ok := assertIsService(obj); ok {
		subCachePath := append(kd.domainPath, serviceSubdomain, s.Namespace, s.Name)
		kd.cacheLock.Lock()
		defer kd.cacheLock.Unlock()
		success := kd.cache.deletePath(subCachePath...)
		glog.V(2).Infof("Removing service %v at path %v. Success: ", s.Name, subCachePath, success)
		// ExternalName services have no IP
		if kapi.IsServiceIPSet(s) {
			delete(kd.reverseRecordMap, s.Spec.ClusterIP)
			delete(kd.clusterIPServiceMap, s.Spec.ClusterIP)
		}
	}
}
Esempio n. 18
0
func (rly *relay) addServersUsingEndpoints(e *kubeAPI.Endpoints) error {
	rly.mlock.Lock()
	defer rly.mlock.Unlock()
	svc, err := rly.getServiceFromEndpoints(e)
	if err != nil {
		return err
	}
	if svc == nil || kubeAPI.IsServiceIPSet(svc) {
		log.WithField("endpoints", e).Info("No headless service found corresponding to Endpoints.")
		return nil
	}

	return rly.syncServersForHeadlessService(e, svc)
}
Esempio n. 19
0
func (oc *OsdnController) watchServices() {
	services := make(map[string]*kapi.Service)
	eventQueue := oc.Registry.RunEventQueue(Services)

	for {
		eventType, obj, err := eventQueue.Pop()
		if err != nil {
			utilruntime.HandleError(fmt.Errorf("EventQueue failed for services: %v", err))
			return
		}
		serv := obj.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(serv) {
			continue
		}

		switch eventType {
		case watch.Added, watch.Modified:
			oldsvc, exists := services[string(serv.UID)]
			if exists {
				if !isServiceChanged(oldsvc, serv) {
					continue
				}
				if err := oc.pluginHooks.DeleteServiceRules(oldsvc); err != nil {
					log.Error(err)
				}
			}

			netid, err := oc.WaitAndGetVNID(serv.Namespace)
			if err != nil {
				log.Errorf("Skipped adding service rules for serviceEvent: %v, Error: %v", eventType, err)
				continue
			}

			if err := oc.pluginHooks.AddServiceRules(serv, netid); err != nil {
				log.Error(err)
				continue
			}
			services[string(serv.UID)] = serv
		case watch.Deleted:
			delete(services, string(serv.UID))

			if err := oc.pluginHooks.DeleteServiceRules(serv); err != nil {
				log.Error(err)
			}
		}
	}
}
Esempio n. 20
0
func (registry *Registry) getServices(namespace string) ([]kapi.Service, error) {
	kServList, err := registry.kClient.Services(namespace).List(kapi.ListOptions{})
	if err != nil {
		return nil, err
	}

	servList := make([]kapi.Service, 0, len(kServList.Items))
	for _, service := range kServList.Items {
		if !kapi.IsServiceIPSet(&service) {
			continue
		}
		servList = append(servList, service)
	}
	return servList, nil
}
Esempio n. 21
0
func (registry *Registry) getServices(namespace string) ([]osdnapi.Service, string, error) {
	kServList, err := registry.kClient.Services(namespace).List(kapi.ListOptions{})
	if err != nil {
		return nil, "", err
	}

	oServList := make([]osdnapi.Service, 0, len(kServList.Items))
	for _, kService := range kServList.Items {
		if !kapi.IsServiceIPSet(&kService) {
			continue
		}
		oServList = append(oServList, newSDNService(&kService))
	}
	return oServList, kServList.ListMeta.ResourceVersion, nil
}
Esempio n. 22
0
func (oi *OsdnRegistryInterface) getServices(namespace string) ([]osdnapi.Service, string, error) {
	kServList, err := oi.kClient.Services(namespace).List(labels.Everything(), fields.Everything())
	if err != nil {
		return nil, "", err
	}

	oServList := make([]osdnapi.Service, 0, len(kServList.Items))
	for _, kService := range kServList.Items {
		if !kapi.IsServiceIPSet(&kService) {
			continue
		}
		oServList = append(oServList, newSDNService(&kService))
	}
	return oServList, kServList.ListMeta.ResourceVersion, nil
}
Esempio n. 23
0
func isServiceValid(service *kapi.Service) bool {
	if isServiceNameValid(service.Name) {
		if kapi.IsServiceIPSet(service) {
			if service.Spec.Type == kapi.ServiceTypeNodePort {
				return true // Service is valid
			}
			//Currently this is only for NodePorts.
			glog.V(3).Infof("Skipping non-NodePort service: %s\n", service.Name)
		} else {
			// if ClusterIP is not set, do not create a DNS records
			glog.Infof("Skipping dns record for headless service: %s\n", service.Name)
		}
	}

	return false
}
Esempio n. 24
0
func (ks *kube2sky) addDNSUsingEndpoints(subdomain string, e *kapi.Endpoints) error {
	ks.mlock.Lock()
	defer ks.mlock.Unlock()
	svc, err := ks.getServiceFromEndpoints(e)
	if err != nil {
		return err
	}
	if svc == nil || kapi.IsServiceIPSet(svc) {
		// No headless service found corresponding to endpoints object.
		return nil
	}
	// Remove existing DNS entry.
	if err := ks.removeDNS(subdomain); err != nil {
		return err
	}
	return ks.generateRecordsForHeadlessService(subdomain, e, svc)
}
Esempio n. 25
0
func (node *OsdnNode) updatePodNetwork(namespace string, oldNetID, netID uint32) error {
	// FIXME: this is racy; traffic coming from the pods gets switched to the new
	// VNID before the service and firewall rules are updated to match. We need
	// to do the updates as a single transaction (ovs-ofctl --bundle).

	pods, err := node.GetLocalPods(namespace)
	if err != nil {
		return err
	}
	services, err := node.kClient.Services(namespace).List(kapi.ListOptions{})
	if err != nil {
		return err
	}

	errList := []error{}

	// Update OF rules for the existing/old pods in the namespace
	for _, pod := range pods {
		err = node.UpdatePod(pod.Namespace, pod.Name, kubetypes.DockerID(getPodContainerID(&pod)))
		if err != nil {
			errList = append(errList, err)
		}
	}

	// Update OF rules for the old services in the namespace
	for _, svc := range services.Items {
		if !kapi.IsServiceIPSet(&svc) {
			continue
		}

		if err = node.DeleteServiceRules(&svc); err != nil {
			log.Error(err)
		}
		if err = node.AddServiceRules(&svc, netID); err != nil {
			errList = append(errList, err)
		}
	}

	// Update namespace references in egress firewall rules
	if err = node.UpdateEgressNetworkPolicyVNID(namespace, oldNetID, netID); err != nil {
		errList = append(errList, err)
	}

	return kerrors.NewAggregate(errList)
}
Esempio n. 26
0
func (mp *multiTenantPlugin) updatePodNetwork(namespace string, oldNetID, netID uint32) {
	// FIXME: this is racy; traffic coming from the pods gets switched to the new
	// VNID before the service and firewall rules are updated to match. We need
	// to do the updates as a single transaction (ovs-ofctl --bundle).

	pods, err := mp.node.GetLocalPods(namespace)
	if err != nil {
		glog.Errorf("Could not get list of local pods in namespace %q: %v", namespace, err)
	}
	services, err := mp.node.kClient.Core().Services(namespace).List(kapi.ListOptions{})
	if err != nil {
		glog.Errorf("Could not get list of services in namespace %q: %v", namespace, err)
		services = &kapi.ServiceList{}
	}

	movedVNIDRefs := 0

	// Update OF rules for the existing/old pods in the namespace
	for _, pod := range pods {
		err = mp.node.UpdatePod(pod)
		if err == nil {
			movedVNIDRefs++
		} else {
			glog.Errorf("Could not update pod %q in namespace %q: %v", pod.Name, namespace, err)
		}
	}

	// Update OF rules for the old services in the namespace
	for _, svc := range services.Items {
		if !kapi.IsServiceIPSet(&svc) {
			continue
		}

		mp.node.DeleteServiceRules(&svc)
		mp.node.AddServiceRules(&svc, netID)
		movedVNIDRefs++
	}

	if movedVNIDRefs > 0 {
		mp.moveVNIDRefs(movedVNIDRefs, oldNetID, netID)
	}

	// Update namespace references in egress firewall rules
	mp.node.UpdateEgressNetworkPolicyVNID(namespace, oldNetID, netID)
}
Esempio n. 27
0
func (node *OsdnNode) watchServices() {
	services := make(map[string]*kapi.Service)
	RunEventQueue(node.kClient.CoreClient, Services, func(delta cache.Delta) error {
		serv := delta.Object.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(serv) {
			return nil
		}

		log.V(5).Infof("Watch %s event for Service %q", delta.Type, serv.ObjectMeta.Name)
		switch delta.Type {
		case cache.Sync, cache.Added, cache.Updated:
			oldsvc, exists := services[string(serv.UID)]
			if exists {
				if !isServiceChanged(oldsvc, serv) {
					break
				}
				node.DeleteServiceRules(oldsvc)
			}

			netid, err := node.policy.GetVNID(serv.Namespace)
			if err != nil {
				return fmt.Errorf("skipped adding service rules for serviceEvent: %v, Error: %v", delta.Type, err)
			}

			node.AddServiceRules(serv, netid)
			services[string(serv.UID)] = serv
			if !exists {
				node.policy.RefVNID(netid)
			}
		case cache.Deleted:
			delete(services, string(serv.UID))
			node.DeleteServiceRules(serv)

			netid, err := node.policy.GetVNID(serv.Namespace)
			if err == nil {
				node.policy.UnrefVNID(netid)
			}
		}
		return nil
	})
}
Esempio n. 28
0
func (kd *KubeDNS) newService(obj interface{}) {
	if service, ok := assertIsService(obj); ok {
		glog.V(4).Infof("Add/Updated for service %v", service.Name)
		// ExternalName services are a special kind that return CNAME records
		if service.Spec.Type == kapi.ServiceTypeExternalName {
			kd.newExternalNameService(service)
			return
		}
		// if ClusterIP is not set, a DNS entry should not be created
		if !kapi.IsServiceIPSet(service) {
			kd.newHeadlessService(service)
			return
		}
		if len(service.Spec.Ports) == 0 {
			glog.Warningf("Unexpected service with no ports, this should not have happened: %v", service)
		}
		kd.newPortalService(service)
	}
}
Esempio n. 29
0
func (rs *REST) Delete(ctx genericapirequest.Context, id string) (runtime.Object, error) {
	service, err := rs.registry.GetService(ctx, id, &metav1.GetOptions{})
	if err != nil {
		return nil, err
	}

	err = rs.registry.DeleteService(ctx, id)
	if err != nil {
		return nil, err
	}

	// TODO: can leave dangling endpoints, and potentially return incorrect
	// endpoints if a new service is created with the same name
	err = rs.endpoints.DeleteEndpoints(ctx, id)
	if err != nil && !errors.IsNotFound(err) {
		return nil, err
	}

	if api.IsServiceIPSet(service) {
		rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP))
	}

	for _, nodePort := range CollectServiceNodePorts(service) {
		err := rs.serviceNodePorts.Release(nodePort)
		if err != nil {
			// these should be caught by an eventual reconciliation / restart
			glog.Errorf("Error releasing service %s node port %d: %v", service.Name, nodePort, err)
		}
	}

	if shouldCheckOrAssignHealthCheckNodePort(service) {
		nodePort := apiservice.GetServiceHealthCheckNodePort(service)
		if nodePort > 0 {
			err := rs.serviceNodePorts.Release(int(nodePort))
			if err != nil {
				// these should be caught by an eventual reconciliation / restart
				utilruntime.HandleError(fmt.Errorf("Error releasing service health check %s node port %d: %v", service.Name, nodePort, err))
			}
		}
	}
	return &metav1.Status{Status: metav1.StatusSuccess}, nil
}
Esempio n. 30
0
func (node *OsdnNode) watchServices() {
	services := make(map[string]*kapi.Service)
	node.registry.RunEventQueue(Services, func(delta cache.Delta) error {
		serv := delta.Object.(*kapi.Service)

		// Ignore headless services
		if !kapi.IsServiceIPSet(serv) {
			return nil
		}

		log.V(5).Infof("Watch %s event for Service %q", delta.Type, serv.ObjectMeta.Name)
		switch delta.Type {
		case cache.Sync, cache.Added, cache.Updated:
			oldsvc, exists := services[string(serv.UID)]
			if exists {
				if !isServiceChanged(oldsvc, serv) {
					break
				}
				if err := node.DeleteServiceRules(oldsvc); err != nil {
					log.Error(err)
				}
			}

			netid, err := node.vnids.WaitAndGetVNID(serv.Namespace)
			if err != nil {
				return fmt.Errorf("skipped adding service rules for serviceEvent: %v, Error: %v", delta.Type, err)
			}

			if err = node.AddServiceRules(serv, netid); err != nil {
				return err
			}
			services[string(serv.UID)] = serv
		case cache.Deleted:
			delete(services, string(serv.UID))
			if err := node.DeleteServiceRules(serv); err != nil {
				return err
			}
		}
		return nil
	})
}