Example #1
0
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
}
Example #2
0
// 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
	err = gCfg.Write()
	if err != nil {
		log.Errorf("error updating tenant '%s'.Error: %s", tenant.Name, err)
		return err
	}

	tempRm, err := resources.GetStateResourceManager()
	if err != nil {
		return err
	}

	err = gCfg.Process(core.ResourceManager(tempRm))
	if err != nil {
		log.Errorf("Error updating the config %+v. Error: %s", gCfg, err)
		return err
	}

	err = startServiceContainer(tenant.Name)
	if err != nil {
		log.Errorf("Error starting service container. Err: %v", err)
		return err
	}

	return nil
}
Example #3
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(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
}
Example #4
0
func validateOpts(opts *cliOpts) error {
	var err error

	if flagSet.NArg() != 1 || opts.help {
		usage()
		return nil
	}

	if opts.debug {
		log.SetLevel(log.DebugLevel)
	}

	if opts.oper.Get() == "" {
		log.Fatalf("An operation must be specified")
	}

	if opts.construct.Get() == "" {
		log.Fatalf("A construct must be specified")
	}

	if opts.pktTagType != "vxlan" && opts.pktTagType != "vlan" {
		log.Fatalf("error '%s' packet tag type not supported", opts.pktTagType)
	}

	// global create params validation
	if opts.oper.Get() == cliOperCreate &&
		opts.construct.Get() == cliConstructGlobal {
		if opts.vlans != "" {
			_, err = netutils.ParseTagRanges(opts.vlans, "vlan")
			if err != nil {
				log.Fatalf("error '%s' parsing vlan range '%s' \n", err, opts.vlans)
			}
		}

		if opts.vxlans != "" {
			_, err = netutils.ParseTagRanges(opts.vxlans, "vxlan")
			if err != nil {
				log.Fatalf("error '%s' parsing vxlan range '%s' \n", err, opts.vxlans)
			}
		}
	}

	if opts.pktTag == "auto" {
		if opts.oper.Get() == cliOperCreate &&
			opts.construct.Get() == cliConstructNetwork {
			log.Infof("  auto allocating network subnet from global pool")
		}
	} else if opts.pktTag != "" {
		_, err = strconv.Atoi(opts.pktTag)
		if err != nil {
			log.Fatalf("Error convertinng tag %s to integer \n", opts.pktTag)
		}
	}

	// network create params validation
	if opts.oper.Get() == cliOperCreate &&
		opts.construct.Get() == cliConstructNetwork {
	}

	if opts.homingHost == "" {
		opts.homingHost, err = os.Hostname()
		if err != nil {
			log.Fatalf("error obtaining the hostname, error %s \n", err)
		}
	}

	// default gw and mask parsing
	if opts.subnetCidr == "" {
		opts.subnetLen = 0
		opts.subnetIP = "auto"
	} else {
		_, _, err = net.ParseCIDR(opts.subnetCidr)
		if err != nil {
			log.Fatalf("error '%s' parsing cidr ip %s \n", err, opts.subnetCidr)
		}

		opts.subnetIP, opts.subnetLen, err = netutils.ParseCIDR(opts.subnetCidr)
		if err != nil {
			logFatalSubnetAndMaskFormatError()
		}
	}

	if opts.vtepIP != "" && net.ParseIP(opts.vtepIP) == nil {
		log.Fatalf("error '%s' parsing vtep ip %s \n", err, opts.vtepIP)
	}

	// endpoint parameters validation
	if opts.oper.Get() == cliOperCreate &&
		opts.construct.Get() == cliConstructEndpoint &&
		opts.vtepIP != "" &&
		(opts.netID == "" || opts.ipAddr == "") {
		if opts.ipAddr == "auto" {
			log.Debugf("doing auto ip address assignemt for the ep... \n")
		} else {
			log.Fatalf("Endpoint creation requires a valid net-id, vlan tag, " +
				"and ip address")
		}
	}

	// attach detach parameters validation
	if (opts.oper.Get() == cliOperAttach || opts.oper.Get() == cliOperDetach) &&
		opts.construct.Get() == cliConstructEndpoint && opts.contName == "" {
		log.Fatalf("A valid container-id is needed to attach/detach a container to an ep")
	}

	return err
}
Example #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(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" {
		nwCfg.ExtPktTag = network.PktTag
		nwCfg.PktTag = network.PktTag
	} else if network.PktTagType == "vlan" {
		nwCfg.PktTag = network.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.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
	}

	// Create the network in docker
	subnetCIDR := fmt.Sprintf("%s/%d", nwCfg.SubnetIP, nwCfg.SubnetLen)
	err = createDockNet(nwCfg.ID, 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, networkID, stateDriver)
	if err != nil {
		log.Errorf("Error attaching service container to network: %s. Err: %v",
			networkID, err)
	}

	return nil
}