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 }
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) }
func (kd *KubeDNS) newService(obj interface{}) { if service, ok := assertIsService(obj); ok { glog.V(4).Infof("Add/Updated for service %v", service.Name) // 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) } }
func (rs *REST) Create(ctx api.Context, obj runtime.Object) (runtime.Object, error) { service := obj.(*api.Service) if err := rest.BeforeCreate(Strategy, ctx, obj); err != nil { return nil, err } // TODO: this should probably move to strategy.PrepareForCreate() releaseServiceIP := false defer func() { if releaseServiceIP { if api.IsServiceIPSet(service) { rs.serviceIPs.Release(net.ParseIP(service.Spec.ClusterIP)) } } }() nodePortOp := portallocator.StartOperation(rs.serviceNodePorts) defer nodePortOp.Finish() if api.IsServiceIPRequested(service) { // Allocate next available. ip, err := rs.serviceIPs.AllocateNext() if err != nil { // TODO: what error should be returned here? It's not a // field-level validation failure (the field is valid), and it's // not really an internal error. return nil, errors.NewInternalError(fmt.Errorf("failed to allocate a serviceIP: %v", err)) } service.Spec.ClusterIP = ip.String() releaseServiceIP = true } else if api.IsServiceIPSet(service) { // Try to respect the requested IP. if err := rs.serviceIPs.Allocate(net.ParseIP(service.Spec.ClusterIP)); err != nil { // TODO: when validation becomes versioned, this gets more complicated. el := field.ErrorList{field.Invalid(field.NewPath("spec", "clusterIP"), service.Spec.ClusterIP, err.Error())} return nil, errors.NewInvalid(api.Kind("Service"), service.Name, el) } releaseServiceIP = true } assignNodePorts := shouldAssignNodePorts(service) for i := range service.Spec.Ports { servicePort := &service.Spec.Ports[i] if servicePort.NodePort != 0 { err := nodePortOp.Allocate(int(servicePort.NodePort)) if err != nil { // TODO: when validation becomes versioned, this gets more complicated. el := field.ErrorList{field.Invalid(field.NewPath("spec", "ports").Index(i).Child("nodePort"), servicePort.NodePort, err.Error())} return nil, errors.NewInvalid(api.Kind("Service"), service.Name, el) } } else if assignNodePorts { nodePort, err := nodePortOp.AllocateNext() if err != nil { // TODO: what error should be returned here? It's not a // field-level validation failure (the field is valid), and it's // not really an internal error. return nil, errors.NewInternalError(fmt.Errorf("failed to allocate a nodePort: %v", err)) } servicePort.NodePort = int32(nodePort) } } out, err := rs.registry.CreateService(ctx, service) if err != nil { err = rest.CheckGeneratedNameError(Strategy, err, service) } if err == nil { el := nodePortOp.Commit() if el != nil { // these should be caught by an eventual reconciliation / restart glog.Errorf("error(s) committing service node-ports changes: %v", el) } releaseServiceIP = false } return out, err }