// 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 }
// 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) }
// 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 }
// 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 }
// 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 }