func validateNetworkConfig(tenant *intent.ConfigTenant) error { var err error if tenant.Name == "" { return core.Errorf("null tenant name") } for _, network := range tenant.Networks { if network.Name == "" { core.Errorf("null network name") } err = checkPktTagType(network.PktTagType) if err != nil { return err } if network.SubnetCIDR != "" { _, _, err = netutils.ParseCIDR(network.SubnetCIDR) if err != nil { return err } } if network.Gateway != "" { if net.ParseIP(network.Gateway) == nil { return core.Errorf("invalid IP") } } } return err }
func checkDocknetCreate(t *testing.T, tenantName, networkName, serviceName, subnet, gw string) { docknetName := GetDocknetName(tenantName, networkName, serviceName) subnetIP, subnetLen, _ := netutils.ParseCIDR(subnet) nwcfg := mastercfg.CfgNetworkState{ Tenant: tenantName, NetworkName: networkName, PktTagType: "vlan", PktTag: 1, ExtPktTag: 1, SubnetIP: subnetIP, SubnetLen: subnetLen, Gateway: gw, } // create a docker network err := CreateDockNet(tenantName, networkName, serviceName, &nwcfg) if err != nil { t.Fatalf("Error creating docker ntework. Err: %v", err) } // verify docknet state is created dnetOper := getDocknetState(tenantName, networkName, serviceName) if dnetOper == nil { t.Fatalf("Error finding docknet state for %s", docknetName) } // check if docker has the state docker, err := utils.GetDockerClient() if err != nil { t.Fatalf("Unable to connect to docker. Error %v", err) } ninfo, err := docker.InspectNetwork(docknetName) if err != nil { t.Fatalf("Error getting network info for %s. Err: %v", docknetName, err) } // verify params are correct if ninfo.Scope != "local" || ninfo.Driver != netDriverName || ninfo.IPAM.Driver != ipamDriverName || ninfo.IPAM.Config[0].Subnet != subnet || ninfo.IPAM.Config[0].Gateway != gw { t.Fatalf("Docker network {%+v} does not match expected values", ninfo) } // make sure FindDocknetByUUID returns correct UUID tmpOper, err := FindDocknetByUUID(dnetOper.DocknetUUID) if err != nil { t.Fatalf("Error getting docknet by UUID") } if tmpOper.TenantName != tenantName || tmpOper.NetworkName != networkName || tmpOper.ServiceName != serviceName { t.Fatalf("Got unexpected docknet oper state %+v for network UUID %s", tmpOper, dnetOper.DocknetUUID) } }
// CreateTenant sets the tenant's state according to the passed ConfigTenant. func CreateTenant(stateDriver core.StateDriver, tenant *intent.ConfigTenant) error { gOper := &gstate.Oper{} gOper.StateDriver = stateDriver err := gOper.Read(tenant.Name) if err == nil { return err } err = validateTenantConfig(tenant) if err != nil { return err } gCfg := &gstate.Cfg{} gCfg.StateDriver = stateDriver gCfg.Version = gstate.VersionBeta1 gCfg.Tenant = tenant.Name gCfg.Deploy.DefaultNetType = tenant.DefaultNetType gCfg.Deploy.DefaultNetwork = tenant.DefaultNetwork gCfg.Auto.SubnetPool, gCfg.Auto.SubnetLen, _ = netutils.ParseCIDR(tenant.SubnetPool) gCfg.Auto.VLANs = tenant.VLANs gCfg.Auto.VXLANs = tenant.VXLANs gCfg.Auto.AllocSubnetLen = tenant.AllocSubnetLen tempRm, err := resources.GetStateResourceManager() if err != nil { return err } // setup resources err = gCfg.Process(core.ResourceManager(tempRm)) if err != nil { log.Errorf("Error updating the config %+v. Error: %s", gCfg, err) return err } // start skydns container err = startServiceContainer(tenant.Name) if err != nil { log.Errorf("Error starting service container. Err: %v", err) return err } err = gCfg.Write() if err != nil { log.Errorf("error updating tenant '%s'.Error: %s", tenant.Name, err) 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) 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 }
// 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 }
// 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 }