func (a *Allocator) taskCreateNetworkAttachments(t *api.Task, s *api.Service) { // If task network attachments have already been filled in no // need to do anything else. if len(t.Networks) != 0 { return } var networks []*api.NetworkAttachment if isIngressNetworkNeeded(s) { networks = append(networks, &api.NetworkAttachment{Network: a.netCtx.ingressNetwork}) } a.store.View(func(tx store.ReadTx) { // Always prefer NetworkAttachmentConfig in the TaskSpec specNetworks := t.Spec.Networks if len(specNetworks) == 0 && s != nil && len(s.Spec.Networks) != 0 { specNetworks = s.Spec.Networks } for _, na := range specNetworks { n := store.GetNetwork(tx, na.Target) if n == nil { continue } attachment := api.NetworkAttachment{Network: n} attachment.Aliases = append(attachment.Aliases, na.Aliases...) attachment.Addresses = append(attachment.Addresses, na.Addresses...) networks = append(networks, &attachment) } }) taskUpdateNetworks(t, networks) }
// allocate the IP addresses for a single network attachment of the task. func (na *NetworkAllocator) allocateNetworkIPs(nAttach *api.NetworkAttachment) error { var ip *net.IPNet ipam, _, _, err := na.resolveIPAM(nAttach.Network) if err != nil { return errors.Wrap(err, "failed to resolve IPAM while allocating") } localNet := na.getNetwork(nAttach.Network.ID) if localNet == nil { return fmt.Errorf("could not find network allocator state for network %s", nAttach.Network.ID) } addresses := nAttach.Addresses if len(addresses) == 0 { addresses = []string{""} } for i, rawAddr := range addresses { var addr net.IP if rawAddr != "" { var err error addr, _, err = net.ParseCIDR(rawAddr) if err != nil { addr = net.ParseIP(rawAddr) if addr == nil { return errors.Wrapf(err, "could not parse address string %s", rawAddr) } } } for _, poolID := range localNet.pools { var err error ip, _, err = ipam.RequestAddress(poolID, addr, nil) if err != nil && err != ipamapi.ErrNoAvailableIPs && err != ipamapi.ErrIPOutOfRange { return errors.Wrap(err, "could not allocate IP from IPAM") } // If we got an address then we are done. if err == nil { ipStr := ip.String() localNet.endpoints[ipStr] = poolID addresses[i] = ipStr nAttach.Addresses = addresses return nil } } } return errors.New("could not find an available IP") }
func (a *Allocator) taskCreateNetworkAttachments(t *api.Task, s *api.Service) { // If task network attachments have already been filled in no // need to do anything else. if len(t.Networks) != 0 { return } var networks []*api.NetworkAttachment // The service to which this task belongs is trying to expose // ports to the external world. Automatically attach the task // to the ingress network. if s != nil && s.Spec.Endpoint != nil && len(s.Spec.Endpoint.Ports) != 0 { networks = append(networks, &api.NetworkAttachment{Network: a.netCtx.ingressNetwork}) } a.store.View(func(tx store.ReadTx) { // Always prefer NetworkAttachmentConfig in the TaskSpec specNetworks := t.Spec.Networks if len(specNetworks) == 0 && s != nil && len(s.Spec.Networks) != 0 { specNetworks = s.Spec.Networks } for _, na := range specNetworks { n := store.GetNetwork(tx, na.Target) if n == nil { continue } attachment := api.NetworkAttachment{Network: n} attachment.Aliases = append(attachment.Aliases, na.Aliases...) attachment.Addresses = append(attachment.Addresses, na.Addresses...) networks = append(networks, &attachment) } }) taskUpdateNetworks(t, networks) }