Beispiel #1
0
// DeleteEndpointGroup handles endpoint group deletes
func DeleteEndpointGroup(tenantName, groupName string) error {
	// Get the state driver
	stateDriver, err := utils.GetStateDriver()
	if err != nil {
		return err
	}

	epgKey := mastercfg.GetEndpointGroupKey(groupName, tenantName)
	epgCfg := &mastercfg.EndpointGroupState{}
	epgCfg.StateDriver = stateDriver
	err = epgCfg.Read(epgKey)
	if err != nil {
		log.Errorf("error reading EPG key %s. Error: %s", epgKey, err)
		return err
	}

	if epgCfg.EpCount != 0 {
		return core.Errorf("Error: EPG %s has active endpoints", groupName)
	}

	// Delete the endpoint group state
	gstate.GlobalMutex.Lock()
	defer gstate.GlobalMutex.Unlock()
	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err = gCfg.Read(epgCfg.TenantName)
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// if aci mode we allocate per-epg vlan. free it here.
	aciMode, aErr := IsAciConfigured()
	if aErr != nil {
		return aErr
	}

	if aciMode {
		if epgCfg.PktTagType == "vlan" {
			err = gCfg.FreeVLAN(uint(epgCfg.PktTag))
			if err != nil {
				return err
			}
			log.Debugf("Freed vlan %v\n", epgCfg.PktTag)
		}
	}

	// Delete endpoint group
	err = epgCfg.Clear()
	if err != nil {
		log.Errorf("error writing epGroup config. Error: %v", err)
		return err
	}

	if GetClusterMode() == "docker" {
		return docknet.DeleteDockNet(epgCfg.TenantName, epgCfg.NetworkName, epgCfg.GroupName)
	}
	return nil
}
Beispiel #2
0
// DeleteEndpointGroup handles endpoint group deletes
func DeleteEndpointGroup(epgID int) error {
	// Get the state driver
	stateDriver, err := utils.GetStateDriver()
	if err != nil {
		return err
	}

	epgCfg := &mastercfg.EndpointGroupState{}
	epgCfg.StateDriver = stateDriver
	err = epgCfg.Read(strconv.Itoa(epgID))
	if err != nil {
		log.Errorf("EpGroup %v is not configured", epgID)
		return err
	}

	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err = gCfg.Read(epgCfg.Tenant)
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// if aci mode we allocate per-epg vlan. free it here.
	aciMode, aErr := IsAciConfigured()
	if aErr != nil {
		return aErr
	}

	if aciMode {
		if epgCfg.PktTagType == "vlan" {
			err = gCfg.FreeVLAN(uint(epgCfg.PktTag))
			if err != nil {
				return err
			}
			log.Debugf("Freed vlan %v\n", epgCfg.PktTag)
		}
	}

	// Delete endpoint group
	err = epgCfg.Clear()
	if err != nil {
		log.Errorf("error writing epGroup config. Error: %v", err)
		return err
	}

	return docknet.DeleteDockNet(epgCfg.Tenant, epgCfg.NetworkName, epgCfg.Name)
}
Beispiel #3
0
func freeNetworkResources(stateDriver core.StateDriver, nwCfg *mastercfg.CfgNetworkState, gCfg *gstate.Cfg) (err error) {
	if nwCfg.PktTagType == "vlan" {
		err = gCfg.FreeVLAN(uint(nwCfg.PktTag))
		if err != nil {
			return err
		}
	} else if nwCfg.PktTagType == "vxlan" {
		log.Infof("freeing vlan %d vxlan %d", nwCfg.PktTag, nwCfg.ExtPktTag)
		err = gCfg.FreeVXLAN(uint(nwCfg.ExtPktTag), uint(nwCfg.PktTag))
		if err != nil {
			return err
		}
	}

	if err := gCfg.UnassignNetwork(nwCfg.ID); err != nil {
		return err
	}

	return err
}
Beispiel #4
0
// processResource handles resource commands
func processResource(stateDriver core.StateDriver, rsrcName, rsrcVal string) error {
	// Read global config
	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err := gCfg.Read("")
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// process resource based on name
	if rsrcName == "vlan" {
		numVlans, vlansInUse := gCfg.GetVlansInUse()
		fmt.Printf("Num Vlans: %d\n Current Vlans in Use: %s\n", numVlans, vlansInUse)

		// see if we need to set the resource
		if rsrcVal != "" {
			values, err := parseRange(rsrcVal)
			if err != nil {
				log.Errorf("Error parsing range: %v", err)
				return err
			}
			log.Infof("Setting vlan values: %v", values)

			// set vlan values
			for _, val := range values {
				_, err = gCfg.AllocVLAN(val)
				if err != nil {
					log.Errorf("Error setting vlan: %d. Err: %v", val, err)
				}
			}

			log.Infof("Finished setting VLANs")
		}
	} else if rsrcName == "vxlan" {
		numVxlans, vxlansInUse := gCfg.GetVxlansInUse()
		fmt.Printf("Num Vxlans: %d\n Current Vxlans in Use: %s\n", numVxlans, vxlansInUse)

		// see if we need to set the resource
		if rsrcVal != "" {
			values, err := parseRange(rsrcVal)
			if err != nil {
				log.Errorf("Error parsing range: %v", err)
				return err
			}
			log.Infof("Setting vxlan values: %v", values)

			// set vlan values
			for _, val := range values {
				_, _, err = gCfg.AllocVXLAN(val)
				if err != nil {
					log.Errorf("Error setting vxlan: %d. Err: %v", val, err)
				}
			}

			log.Infof("Finished setting VXLANs")
		}
	} else {
		log.Errorf("Unknown resource: %v", rsrcName)
		return fmt.Errorf("Unknown resource")
	}

	return nil
}
Beispiel #5
0
// CreateNetwork creates a network from intent
func CreateNetwork(network intent.ConfigNetwork, stateDriver core.StateDriver, tenantName string) error {
	var extPktTag, pktTag uint

	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err := gCfg.Read("")
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// Create network state
	networkID := network.Name + "." + tenantName
	nwCfg := &mastercfg.CfgNetworkState{}
	nwCfg.StateDriver = stateDriver
	if nwCfg.Read(networkID) == nil {
		// TODO: check if parameters changed and apply an update if needed
		return nil
	}

	subnetIP, subnetLen, _ := netutils.ParseCIDR(network.SubnetCIDR)
	err = netutils.ValidateNetworkRangeParams(subnetIP, subnetLen)
	if err != nil {
		return err
	}

	ipv6Subnet, ipv6SubnetLen, _ := netutils.ParseCIDR(network.IPv6SubnetCIDR)

	// construct and update network state
	nwCfg = &mastercfg.CfgNetworkState{
		Tenant:        tenantName,
		NetworkName:   network.Name,
		NwType:        network.NwType,
		PktTagType:    network.PktTagType,
		SubnetIP:      subnetIP,
		SubnetLen:     subnetLen,
		IPv6Subnet:    ipv6Subnet,
		IPv6SubnetLen: ipv6SubnetLen,
	}

	nwCfg.ID = networkID
	nwCfg.StateDriver = stateDriver

	// Allocate pkt tags
	reqPktTag := uint(network.PktTag)
	if nwCfg.PktTagType == "vlan" {
		pktTag, err = gCfg.AllocVLAN(reqPktTag)
		if err != nil {
			return err
		}
	} else if nwCfg.PktTagType == "vxlan" {
		extPktTag, pktTag, err = gCfg.AllocVXLAN(reqPktTag)
		if err != nil {
			return err
		}
	}

	nwCfg.ExtPktTag = int(extPktTag)
	nwCfg.PktTag = int(pktTag)

	netutils.InitSubnetBitset(&nwCfg.IPAllocMap, nwCfg.SubnetLen)
	subnetAddr := netutils.GetSubnetAddr(nwCfg.SubnetIP, nwCfg.SubnetLen)
	nwCfg.SubnetIP = subnetAddr
	nwCfg.IPAddrRange = netutils.GetIPAddrRange(subnetIP, subnetLen)

	if network.Gateway != "" {
		nwCfg.Gateway = network.Gateway

		// Reserve gateway IP address if gateway is specified
		ipAddrValue, err := netutils.GetIPNumber(subnetAddr, nwCfg.SubnetLen, 32, nwCfg.Gateway)
		if err != nil {
			log.Errorf("Error parsing gateway address %s. Err: %v", nwCfg.Gateway, err)
			return err
		}
		nwCfg.IPAllocMap.Set(ipAddrValue)
	}

	if strings.Contains(subnetIP, "-") {
		netutils.SetBitsOutsideRange(&nwCfg.IPAllocMap, subnetIP, subnetLen)
	}

	if network.IPv6Gateway != "" {
		nwCfg.IPv6Gateway = network.IPv6Gateway

		// Reserve gateway IPv6 address if gateway is specified
		hostID, err := netutils.GetIPv6HostID(nwCfg.IPv6Subnet, nwCfg.IPv6SubnetLen, nwCfg.IPv6Gateway)
		if err != nil {
			log.Errorf("Error parsing gateway address %s. Err: %v", nwCfg.IPv6Gateway, err)
			return err
		}
		netutils.ReserveIPv6HostID(hostID, &nwCfg.IPv6AllocMap)
	}

	err = nwCfg.Write()
	if err != nil {
		return err
	}

	// Skip docker and service container configs for infra nw
	if network.NwType == "infra" {
		return nil
	}

	aci, _ := IsAciConfigured()
	if aci {
		// Skip docker network creation for ACI fabric mode.
		return nil
	}

	if GetClusterMode() == "docker" {
		// Create the network in docker
		err = docknet.CreateDockNet(tenantName, network.Name, "", nwCfg)
		if err != nil {
			log.Errorf("Error creating network %s in docker. Err: %v", nwCfg.ID, err)
			return err
		}
	}

	if IsDNSEnabled() {
		// Attach service container endpoint to the network
		err = attachServiceContainer(tenantName, network.Name, stateDriver)
		if err != nil {
			log.Errorf("Error attaching service container to network: %s. Err: %v",
				networkID, err)
			return err
		}
	}

	return nil
}
Beispiel #6
0
// CreateEndpointGroup handles creation of endpoint group
func CreateEndpointGroup(tenantName, networkName, groupName string) error {
	var epgID int

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

	// Read global config
	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err = gCfg.Read(tenantName)
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// read the network config
	networkID := networkName + "." + tenantName
	nwCfg := &mastercfg.CfgNetworkState{}
	nwCfg.StateDriver = stateDriver
	err = nwCfg.Read(networkID)
	if err != nil {
		log.Errorf("Could not find network %s. Err: %v", networkID, err)
		return err
	}

	// params for docker network
	if GetClusterMode() == "docker" {
		// Create each EPG as a docker network
		err = docknet.CreateDockNet(tenantName, networkName, groupName, nwCfg)
		if err != nil {
			log.Errorf("Error creating docker network for group %s.%s. Err: %v", networkName, groupName, err)
			return err
		}
	}

	// assign unique endpoint group ids
	// FIXME: This is a hack. need to add a epgID resource
	for i := 0; i < maxEpgID; i++ {
		epgID = globalEpgID
		globalEpgID = globalEpgID + 1
		if globalEpgID > maxEpgID {
			globalEpgID = 1
		}
		epgCfg := &mastercfg.EndpointGroupState{}
		epgCfg.StateDriver = stateDriver
		err = epgCfg.Read(strconv.Itoa(epgID))
		if err != nil {
			break
		}
	}

	// Create epGroup state
	epgCfg := &mastercfg.EndpointGroupState{
		GroupName:       groupName,
		TenantName:      tenantName,
		NetworkName:     networkName,
		EndpointGroupID: epgID,
		PktTagType:      nwCfg.PktTagType,
		PktTag:          nwCfg.PktTag,
		ExtPktTag:       nwCfg.ExtPktTag,
	}

	epgCfg.StateDriver = stateDriver
	epgCfg.ID = mastercfg.GetEndpointGroupKey(groupName, tenantName)
	log.Debugf("##Create EpGroup %v network %v tagtype %v", groupName, networkName, nwCfg.PktTagType)

	// if aci mode allocate per-epg vlan. otherwise, stick to per-network vlan
	aciMode, rErr := IsAciConfigured()
	if rErr != nil {
		return rErr
	}

	// Special handling for ACI mode
	if aciMode {
		if epgCfg.PktTagType != "vlan" {
			log.Errorf("Network type must be VLAN for ACI mode")
			return errors.New("Network type must be VLAN for ACI mode")
		}

		pktTag, err := gCfg.AllocVLAN(0)
		if err != nil {
			return err
		}
		epgCfg.PktTag = int(pktTag)
		log.Debugf("ACI -- Allocated vlan %v for epg %v", pktTag, groupName)

	}

	err = epgCfg.Write()
	if err != nil {
		return err
	}

	return nil
}
// CreateNetwork creates a network from intent
func CreateNetwork(network intent.ConfigNetwork, stateDriver core.StateDriver, tenantName string) error {
	var extPktTag, pktTag uint

	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err := gCfg.Read("")
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// Create network state
	networkID := network.Name + "." + tenantName
	nwCfg := &mastercfg.CfgNetworkState{}
	nwCfg.StateDriver = stateDriver
	if nwCfg.Read(networkID) == nil {
		// TODO: check if parameters changed and apply an update if needed
		return nil
	}

	subnetIP, subnetLen, _ := netutils.ParseCIDR(network.SubnetCIDR)

	// construct and update network state
	nwCfg = &mastercfg.CfgNetworkState{
		Tenant:      tenantName,
		NetworkName: network.Name,
		PktTagType:  network.PktTagType,
		SubnetIP:    subnetIP,
		SubnetLen:   subnetLen,
		Gateway:     network.Gateway,
	}

	nwCfg.ID = networkID
	nwCfg.StateDriver = stateDriver

	// Allocate pkt tags
	reqPktTag := uint(network.PktTag)
	if nwCfg.PktTagType == "vlan" {
		pktTag, err = gCfg.AllocVLAN(reqPktTag)
		if err != nil {
			return err
		}
	} else if nwCfg.PktTagType == "vxlan" {
		extPktTag, pktTag, err = gCfg.AllocVXLAN(reqPktTag)
		if err != nil {
			return err
		}
	}

	nwCfg.ExtPktTag = int(extPktTag)
	nwCfg.PktTag = int(pktTag)

	// Reserve gateway IP address
	ipAddrValue, err := netutils.GetIPNumber(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, nwCfg.Gateway)
	if err != nil {
		log.Errorf("Error parsing gateway address %s. Err: %v", nwCfg.Gateway, err)
		return err
	}
	nwCfg.IPAllocMap.Set(ipAddrValue)

	netutils.InitSubnetBitset(&nwCfg.IPAllocMap, nwCfg.SubnetLen)
	err = nwCfg.Write()
	if err != nil {
		return err
	}

	if GetClusterMode() == "docker" {
		// Create the network in docker
		subnetCIDR := fmt.Sprintf("%s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen)
		err = createDockNet(tenantName, network.Name, "", subnetCIDR, nwCfg.Gateway)
		if err != nil {
			log.Errorf("Error creating network %s in docker. Err: %v", nwCfg.ID, err)
			return err
		}

		// Attach service container endpoint to the network
		err = attachServiceContainer(tenantName, network.Name, stateDriver)
		if err != nil {
			log.Errorf("Error attaching service container to network: %s. Err: %v",
				networkID, err)
			return err
		}
	}

	return nil
}
// CreateEndpointGroup handles creation of endpoint group
func CreateEndpointGroup(tenantName, networkName, groupName string, epgID int) error {
	// Get the state driver
	stateDriver, err := utils.GetStateDriver()
	if err != nil {
		return err
	}

	// Read global config
	gCfg := gstate.Cfg{}
	gCfg.StateDriver = stateDriver
	err = gCfg.Read(tenantName)
	if err != nil {
		log.Errorf("error reading tenant cfg state. Error: %s", err)
		return err
	}

	// read the network config
	networkID := networkName + "." + tenantName
	nwCfg := &mastercfg.CfgNetworkState{}
	nwCfg.StateDriver = stateDriver
	err = nwCfg.Read(networkID)
	if err != nil {
		log.Errorf("Could not find network %s. Err: %v", networkID, err)
		return err
	}

	// params for docker network
	if GetClusterMode() == "docker" {
		subnetCIDR := fmt.Sprintf("%s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen)

		// Create each EPG as a docker network
		err = createDockNet(tenantName, networkName, groupName, subnetCIDR, nwCfg.Gateway)
		if err != nil {
			log.Errorf("Error creating docker network for group %s.%s. Err: %v", networkName, groupName, err)
			return err
		}
	}

	// Create epGroup state
	epgCfg := &mastercfg.EndpointGroupState{
		Name:        groupName,
		Tenant:      tenantName,
		NetworkName: networkName,
		PktTagType:  nwCfg.PktTagType,
		PktTag:      nwCfg.PktTag,
		ExtPktTag:   nwCfg.ExtPktTag,
	}

	epgCfg.StateDriver = stateDriver
	epgCfg.ID = strconv.Itoa(epgID)
	log.Debugf("##Create EpGroup %v network %v tagtype %v", groupName, networkName, nwCfg.PktTagType)

	// if aci mode allocate per-epg vlan. otherwise, stick to per-network vlan
	aciMode, rErr := IsAciConfigured()
	if rErr != nil {
		return rErr
	}

	// Special handling for ACI mode
	if aciMode {
		if epgCfg.PktTagType != "vlan" {
			log.Errorf("Network type must be VLAN for ACI mode")
			return errors.New("Network type must be VLAN for ACI mode")
		}

		pktTag, err := gCfg.AllocVLAN(0)
		if err != nil {
			return err
		}
		epgCfg.PktTag = int(pktTag)
		log.Debugf("ACI -- Allocated vlan %v for epg %v", pktTag, groupName)

	}

	err = epgCfg.Write()
	if err != nil {
		return err
	}

	return nil
}