Esempio n. 1
0
// networkReleaseAddress release the ip address
func networkReleaseAddress(nwCfg *mastercfg.CfgNetworkState, ipAddress string) error {
	isIPv6 := netutils.IsIPv6(ipAddress)
	if isIPv6 {
		hostID, err := netutils.GetIPv6HostID(nwCfg.SubnetIP, nwCfg.SubnetLen, ipAddress)
		if err != nil {
			log.Errorf("error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				ipAddress, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return err
		}
		// networkReleaseAddress is called from multiple places
		// Make sure we decrement the EpCount only if the IPAddress
		// was not already freed earlier
		if _, found := nwCfg.IPv6AllocMap[hostID]; found {
			nwCfg.EpAddrCount--
		}
		delete(nwCfg.IPv6AllocMap, hostID)
	} else {
		ipAddrValue, err := netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddress)
		if err != nil {
			log.Errorf("error getting host id from hostIP %s Subnet %s/%d. Error: %s",
				ipAddress, nwCfg.SubnetIP, nwCfg.SubnetLen, err)
			return err
		}
		// networkReleaseAddress is called from multiple places
		// Make sure we decrement the EpCount only if the IPAddress
		// was not already freed earlier
		if nwCfg.IPAllocMap.Test(ipAddrValue) {
			nwCfg.EpAddrCount--
		}
		nwCfg.IPAllocMap.Clear(ipAddrValue)
	}

	err := nwCfg.Write()
	if err != nil {
		log.Errorf("error writing nw config. Error: %s", err)
		return err
	}

	return nil
}
Esempio n. 2
0
// AllocAddressHandler allocates addresses
func AllocAddressHandler(w http.ResponseWriter, r *http.Request, vars map[string]string) (interface{}, error) {
	var allocReq AddressAllocRequest

	// Get object from the request
	err := json.NewDecoder(r.Body).Decode(&allocReq)
	if err != nil {
		log.Errorf("Error decoding AllocAddressHandler. Err %v", err)
		return nil, err
	}

	log.Infof("Received AddressAllocRequest: %+v", allocReq)

	// Take a global lock for address allocation
	addrMutex.Lock()
	defer addrMutex.Unlock()

	// Get hold of the state driver
	stateDriver, err := utils.GetStateDriver()
	if err != nil {
		return nil, err
	}

	isIPv6 := netutils.IsIPv6(allocReq.AddressPool)
	networkID := ""

	// Determine the network id to use
	if allocReq.NetworkID != "" {
		networkID = allocReq.NetworkID
	} else {
		// find the network from address pool
		subnetIP := strings.Split(allocReq.AddressPool, "/")[0]
		subnetLen := strings.Split(allocReq.AddressPool, "/")[1]
		tenant := ""
		if strings.Contains(subnetLen, ":") {
			tenant = strings.Split(subnetLen, ":")[1]
			subnetLen = strings.Split(subnetLen, ":")[0]
		}

		// find the network from networkID
		readNet := &mastercfg.CfgNetworkState{}
		readNet.StateDriver = stateDriver
		netList, err := readNet.ReadAll()
		if err != nil {
			if !strings.Contains(err.Error(), "Key not found") {
				log.Errorf("error reading keys during host create. Error: %s", err)
				return nil, err
			}
		}

		for _, ncfg := range netList {
			nw := ncfg.(*mastercfg.CfgNetworkState)
			if isIPv6 && nw.IPv6Subnet == subnetIP && fmt.Sprintf("%d", nw.IPv6SubnetLen) == subnetLen {
				if tenant == "" || nw.Tenant == tenant {
					networkID = nw.ID
				}
			} else if nw.SubnetIP == subnetIP && fmt.Sprintf("%d", nw.SubnetLen) == subnetLen {
				if tenant == "" || nw.Tenant == tenant {
					networkID = nw.ID
				}
			}
		}
	}

	if networkID == "" {
		log.Errorf("Could not find the network for: %s", allocReq.NetworkID)
		return nil, errors.New("Network not found")
	}

	// find the network from network id
	nwCfg := &mastercfg.CfgNetworkState{}
	nwCfg.StateDriver = stateDriver
	err = nwCfg.Read(networkID)
	if err != nil {
		log.Errorf("network %s is not operational", allocReq.NetworkID)
		return nil, err
	}

	// Alloc addresses
	addr, err := networkAllocAddress(nwCfg, allocReq.PreferredIPv4Address, netutils.IsIPv6(allocReq.AddressPool))
	if err != nil {
		log.Errorf("Failed to allocate address. Err: %v", err)
		return nil, err
	}

	var subnetLen uint
	if isIPv6 {
		subnetLen = nwCfg.IPv6SubnetLen
	} else {
		subnetLen = nwCfg.SubnetLen
	}

	// Build the response
	aresp := AddressAllocResponse{
		NetworkID:   allocReq.NetworkID,
		IPv4Address: addr + "/" + fmt.Sprintf("%d", subnetLen),
	}

	return aresp, nil
}