// 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 } } // Get resource manager tempRm, err := resources.GetStateResourceManager() if err != nil { return err } rm := core.ResourceManager(tempRm) // 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(rm) 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(tenantName) if err != nil { log.Errorf("error reading tenant cfg state. Error: %s", err) return err } tempRm, err := resources.GetStateResourceManager() if err != nil { return err } rm := core.ResourceManager(tempRm) // Create network state nwCfg := &drivers.OvsCfgNetworkState{} nwCfg.StateDriver = stateDriver if nwCfg.Read(network.Name) == nil { // TODO: check if parameters changed and apply an update if needed return nil } // construct and update network state nwMasterCfg := &NwConfig{} nwMasterCfg.StateDriver = stateDriver nwMasterCfg.Tenant = tenantName nwMasterCfg.ID = network.Name nwMasterCfg.PktTagType = network.PktTagType nwMasterCfg.PktTag = network.PktTag nwMasterCfg.SubnetIP, nwMasterCfg.SubnetLen, _ = netutils.ParseCIDR(network.SubnetCIDR) nwMasterCfg.DefaultGw = network.DefaultGw nwCfg = &drivers.OvsCfgNetworkState{ Tenant: nwMasterCfg.Tenant, PktTagType: nwMasterCfg.PktTagType, SubnetIP: nwMasterCfg.SubnetIP, SubnetLen: nwMasterCfg.SubnetLen, } nwCfg.StateDriver = stateDriver nwCfg.ID = nwMasterCfg.ID if nwMasterCfg.PktTagType == "" { nwCfg.PktTagType = gCfg.Deploy.DefaultNetType } if nwMasterCfg.PktTag == "" { if nwCfg.PktTagType == "vlan" { pktTag, err = gCfg.AllocVLAN(rm) if err != nil { return err } } else if nwCfg.PktTagType == "vxlan" { extPktTag, pktTag, err = gCfg.AllocVXLAN(rm) if err != nil { return err } } nwCfg.ExtPktTag = int(extPktTag) nwCfg.PktTag = int(pktTag) } else if nwMasterCfg.PktTagType == "vxlan" { // XXX: take local vlan as config, instead of allocating it // independently. Return erro for now, if user tries this config return core.Errorf("Not handled. Need to introduce local-vlan config") } else if nwMasterCfg.PktTagType == "vlan" { nwCfg.PktTag, _ = strconv.Atoi(nwMasterCfg.PktTag) // XXX: do configuration check, to make sure it is allowed } if nwCfg.SubnetIP == "" { nwCfg.SubnetLen = gCfg.Auto.AllocSubnetLen nwCfg.SubnetIP, err = gCfg.AllocSubnet(rm) if err != nil { return err } } nwCfg.DefaultGw = network.DefaultGw if nwCfg.DefaultGw == "" { // TBD: allocate per global policy } netutils.InitSubnetBitset(&nwCfg.IPAllocMap, nwCfg.SubnetLen) err = nwCfg.Write() if err != nil { return err } err = nwMasterCfg.Write() if err != nil { log.Errorf("error writing nw config. Error: %s", err) return err } if nwCfg.PktTagType == "vxlan" { readHost := &HostConfig{} readHost.StateDriver = stateDriver hostCfgs, err := readHost.ReadAll() if err != nil { if !strings.Contains(err.Error(), "Key not found") { log.Errorf("error reading hosts during net add. Error: %s", err) } } for _, hostCfg := range hostCfgs { host := hostCfg.(*HostConfig) err = createVtep(stateDriver, host, nwCfg.ID) if err != nil { log.Errorf("error creating vtep. Error: %s", 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(tenantName) if err != nil { log.Errorf("error reading tenant cfg state. Error: %s", err) return err } tempRm, err := resources.GetStateResourceManager() if err != nil { return err } rm := core.ResourceManager(tempRm) // 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 if network.PktTagType == "" { nwCfg.PktTagType = gCfg.Deploy.DefaultNetType } if network.PktTag == 0 { if nwCfg.PktTagType == "vlan" { pktTag, err = gCfg.AllocVLAN(rm) if err != nil { return err } } else if nwCfg.PktTagType == "vxlan" { extPktTag, pktTag, err = gCfg.AllocVXLAN(rm) if err != nil { return err } } nwCfg.ExtPktTag = int(extPktTag) nwCfg.PktTag = int(pktTag) } else if network.PktTagType == "vxlan" { if !isTagInRange(uint(network.PktTag), "vxlan", gCfg.Auto.VXLANs, stateDriver, tenantName) { return fmt.Errorf("vxlan %d does not adhere to tenant's vxlan range %s", network.PktTag, gCfg.Auto.VXLANs) } nwCfg.ExtPktTag = network.PktTag nwCfg.PktTag = network.PktTag } else if network.PktTagType == "vlan" { if !isTagInRange(uint(network.PktTag), "vlan", gCfg.Auto.VLANs, stateDriver, tenantName) { return fmt.Errorf("vlan %d does not adhere to tenant's vlan range %s", network.PktTag, gCfg.Auto.VLANs) } nwCfg.PktTag = network.PktTag } if nwCfg.SubnetIP == "" { nwCfg.SubnetLen = gCfg.Auto.AllocSubnetLen nwCfg.SubnetIP, err = gCfg.AllocSubnet(rm) if err != nil { return err } nwCfg.SubnetIsAllocated = true } defaultNwName, err := gCfg.AssignDefaultNetwork(network.Name) if err != nil { log.Errorf("error assigning the default network. Error: %s", err) return err } if network.Name == defaultNwName { // For auto derived subnets assign gateway ip be the last valid unicast ip the subnet if nwCfg.Gateway == "" && nwCfg.SubnetIsAllocated { var ipAddrValue uint ipAddrValue = (1 << (32 - nwCfg.SubnetLen)) - 2 nwCfg.Gateway, err = netutils.GetSubnetIP(nwCfg.SubnetIP, nwCfg.SubnetLen, 32, ipAddrValue) if err != nil { 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 }