// Check that container is created with a 'netid' label. This helps us map the // container to a network. This label could be put by one of docker clients (cli, // compose etc) func (adptr *PwrStrpAdptr) handlePreCreate(req *powerStripRequest) (*powerStripResponse, error) { //structure of interesting fields in the create request type DockerCreateRequest struct { Labels map[string]string `json:"Labels"` } dockerReq := &DockerCreateRequest{} err := json.Unmarshal([]byte(req.ClientRequest.Body), dockerReq) if err != nil { return nil, err } if netID, ok := dockerReq.Labels["netid"]; !ok || netID == "" { return nil, core.Errorf("Container doesn't contain a valid 'netid' label. Labels: %+v Body: %q", dockerReq, req.ClientRequest.Body) } else if tenantID, ok := dockerReq.Labels["tenantid"]; !ok || tenantID == "" { return nil, core.Errorf("Container doesn't contain a valid 'tenantid' label. Labels: %+v Body: %q", dockerReq, req.ClientRequest.Body) } else { // XXX: record the outstanding network for which we are yet to receive a // corresponding container-id (in server response). This simplifies things // by assuming that there can't be two outstanding request. Need to revisit // and handle this correctly. adptr.outstandingNet = containerNet{tenantID: tenantID, netID: netID} } return makeClientRequest(req), nil }
// GetIPNumber obtains the host id from the host IP. SEe `GetSubnetIP` for more information. func GetIPNumber(subnetIP string, subnetLen uint, allocSubnetLen uint, hostIP string) (uint, error) { if subnetLen > 32 || subnetLen < 8 { return 0, core.Errorf("subnet length %d not supported", subnetLen) } if subnetLen > allocSubnetLen { return 0, core.Errorf("subnet length %d is bigger than subnet alloc len %d", subnetLen, allocSubnetLen) } hostIPUint32, err := ipv4ToUint32(hostIP) if err != nil { return 0, core.Errorf("unable to convert hostIP %s to uint32", hostIP) } subnetIPUint32, err := ipv4ToUint32(subnetIP) if err != nil { return 0, core.Errorf("unable to convert subnetIP %s to uint32", subnetIP) } hostID := uint((hostIPUint32 - subnetIPUint32) >> (32 - allocSubnetLen)) maxHosts := uint(1 << (allocSubnetLen - subnetLen)) if hostID >= maxHosts { return 0, core.Errorf("hostIP %s is exceeding beyond subnet %s/%d, hostID %d", hostIP, subnetIP, subnetLen, hostID) } return uint(hostID), nil }
// AppCreate creates app state func (ac *APIController) AppCreate(app *contivModel.App) error { log.Infof("Received AppCreate: %+v", app) // Make sure tenant exists if app.TenantName == "" { return core.Errorf("Invalid tenant name") } tenant := contivModel.FindTenant(app.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Setup links modeldb.AddLink(&app.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.Apps, app) // Save the tenant too since we added the links err := tenant.Write() if err != nil { log.Errorf("Error updating tenant state(%+v). Err: %v", tenant, err) return err } CreateAppNw(app) return nil }
// GetIPv6HostID obtains the host id from the host IP. SEe `GetSubnetIP` for more information. func GetIPv6HostID(subnetAddr string, subnetLen uint, hostAddr string) (string, error) { if subnetLen > 128 || subnetLen < 16 { return "", core.Errorf("subnet length %d not supported", subnetLen) } // Initialize hostID hostID := net.IPv6zero var offset uint // get the overlapping byte offset = subnetLen / 8 subnetIP := net.ParseIP(subnetAddr) if subnetIP == nil { return "", core.Errorf("Invalid subnetAddr %s ", subnetAddr) } s := uint8(subnetIP[offset]) hostIP := net.ParseIP(hostAddr) if hostIP == nil { return "", core.Errorf("Invalid hostAddr %s ", hostAddr) } h := uint8(hostIP[offset]) hostID[offset] = byte(h - s) // Copy the rest of the bytes for i := (offset + 1); i < 16; i++ { hostID[i] = hostIP[i] offset++ } return hostID.String(), nil }
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 }
// GetSubnetIPv6 given a subnet IP and host identifier, calculates an IPv6 address // within the subnet for use. func GetSubnetIPv6(subnetAddr string, subnetLen uint, hostID string) (string, error) { if subnetAddr == "" { return "", core.Errorf("null subnet") } if subnetLen > 128 || subnetLen < 16 { return "", core.Errorf("subnet length %d not supported", subnetLen) } subnetIP := net.ParseIP(subnetAddr) hostidIP := net.ParseIP(hostID) hostIP := net.IPv6zero var offset int for offset = 0; offset < int(subnetLen/8); offset++ { hostIP[offset] = subnetIP[offset] } // copy the overlapping byte in subnetIP and hostID if subnetLen%8 != 0 && subnetIP[offset] != 0 { if hostidIP[offset]&subnetIP[offset] != 0 { return "", core.Errorf("host id %s exceeds subnet %s capacity ", hostID, subnetAddr) } hostIP[offset] = hostidIP[offset] | subnetIP[offset] offset++ } for ; offset < len(hostidIP); offset++ { hostIP[offset] = hostidIP[offset] } return hostIP.String(), nil }
// GetSubnetIP given a subnet IP and host identifier, calculates an IP within // the subnet for use. func GetSubnetIP(subnetIP string, subnetLen uint, allocSubnetLen, hostID uint) (string, error) { if subnetIP == "" { return "", core.Errorf("null subnet") } if subnetLen > 32 || subnetLen < 8 { return "", core.Errorf("subnet length %d not supported", subnetLen) } if subnetLen > allocSubnetLen { return "", core.Errorf("subnet length %d is bigger than subnet alloc len %d", subnetLen, allocSubnetLen) } maxHosts := uint(1 << (allocSubnetLen - subnetLen)) if hostID >= maxHosts { return "", core.Errorf("host id %d is beyond subnet's capacity %d", hostID, maxHosts) } hostIPUint32, err := ipv4ToUint32(subnetIP) if err != nil { return "", core.Errorf("unable to convert subnet %s to uint32", subnetIP) } hostIPUint32 += uint32(hostID << (32 - allocSubnetLen)) return ipv4Uint32ToString(hostIPUint32) }
func validateEndpointConfig(stateDriver core.StateDriver, 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") } for _, ep := range network.Endpoints { if ep.Container == "" { return core.Errorf("invalid container name for the endpoint") } if ep.IPAddress != "" { if network.SubnetCIDR != "" { log.Errorf("found ep with ip for auto-allocated net") return core.Errorf("found ep with ip for auto-allocated net") } if net.ParseIP(ep.IPAddress) == nil { return core.Errorf("invalid ep IP") } } } } return err }
func (d *OvsdbDriver) performOvsdbOps(ops []libovsdb.Operation) error { reply, _ := d.ovs.Transact(ovsDataBase, ops...) if len(reply) < len(ops) { return core.Errorf("Unexpected number of replies. Expected: %d, Recvd: %d", len(ops), len(reply)) } ok := true errors := []string{} for i, o := range reply { if o.Error != "" && i < len(ops) { errors = append(errors, fmt.Sprintf("%s(%s)", o.Error, o.Details)) ok = false } else if o.Error != "" { errors = append(errors, fmt.Sprintf("%s(%s)", o.Error, o.Details)) ok = false } } if ok { return nil } log.Errorf("OVS operation failed for op: %+v: Errors: %v", ops, errors) return core.Errorf("ovs operation failed. Error(s): %v", errors) }
// Init the state from configuration. func (r *AutoSubnetCfgResource) Init(rsrcCfg interface{}) error { cfg, ok := rsrcCfg.(*AutoSubnetCfgResource) if !ok { return core.Errorf("Invalid type for subnet resource config") } r.SubnetPool = cfg.SubnetPool r.SubnetPoolLen = cfg.SubnetPoolLen r.AllocSubnetLen = cfg.AllocSubnetLen if cfg.AllocSubnetLen < cfg.SubnetPoolLen { return core.Errorf("AllocSubnetLen should be greater than or equal to SubnetPoolLen") } err := r.Write() if err != nil { return err } defer func() { if err != nil { r.Clear() } }() allocSubnetSize := r.AllocSubnetLen - r.SubnetPoolLen oper := &AutoSubnetOperResource{FreeSubnets: netutils.CreateBitset(allocSubnetSize).Complement()} oper.StateDriver = r.StateDriver oper.ID = r.ID err = oper.Write() if err != nil { return err } return nil }
// ParseTagRanges takes a string such as 12-24,48-64 and turns it into a series // of TagRange. func ParseTagRanges(ranges string, tagType string) ([]TagRange, error) { var err error if ranges == "" { return []TagRange{{0, 0}}, nil } if tagType != "vlan" && tagType != "vxlan" { return nil, core.Errorf("invalid tag type %s", tagType) } rangesStr := strings.Split(ranges, ",") if len(rangesStr) > 1 && tagType == "vxlan" { return nil, core.Errorf("do not support more than 2 vxlan tag ranges") } tagRanges := make([]TagRange, len(rangesStr), len(rangesStr)) for idx, oneRangeStr := range rangesStr { oneRangeStr = strings.Trim(oneRangeStr, " ") tagNums := strings.Split(oneRangeStr, "-") if len(tagNums) > 2 { return nil, core.Errorf("invalid tags %s, correct '10-50,70-100'", oneRangeStr) } tagRanges[idx].Min, err = strconv.Atoi(tagNums[0]) if err != nil { return nil, core.Errorf("invalid integer %d conversion error '%s'", tagRanges[idx].Min, err) } tagRanges[idx].Max, err = strconv.Atoi(tagNums[1]) if err != nil { return nil, core.Errorf("invalid integer %d conversion error '%s'", tagRanges[idx].Max, err) } if tagRanges[idx].Min > tagRanges[idx].Max { return nil, core.Errorf("invalid range %s, min is greater than max", oneRangeStr) } if tagRanges[idx].Min < 1 { return nil, core.Errorf("invalid range %s, values less than 1", oneRangeStr) } if tagType == "vlan" && tagRanges[idx].Max > 4095 { return nil, core.Errorf("invalid range %s, vlan values exceed 4095 max allowed", oneRangeStr) } if tagType == "vxlan" && tagRanges[idx].Max > 65535 { return nil, core.Errorf("invalid range %s, vlan values exceed 65535 max allowed", oneRangeStr) } if tagType == "vxlan" && (tagRanges[idx].Max-tagRanges[idx].Min > 16000) { return nil, core.Errorf("does not allow vxlan range to exceed 16000 range %s", oneRangeStr) } } return tagRanges, nil }
func (gc *Cfg) checkErrors() error { var err error if net.ParseIP(gc.Auto.SubnetPool) == nil { return core.Errorf("invalid ip address pool %s", gc.Auto.SubnetPool) } _, err = netutils.ParseTagRanges(gc.Auto.VLANs, "vlan") if err != nil { return err } _, err = netutils.ParseTagRanges(gc.Auto.VXLANs, "vxlan") if err != nil { return err } if gc.Deploy.DefaultNetType != "vlan" && gc.Deploy.DefaultNetType != "vxlan" { return core.Errorf("unsupported net type %s", gc.Deploy.DefaultNetType) } if gc.Auto.SubnetLen > gc.Auto.AllocSubnetLen { return core.Errorf("subnet size %d is smaller than subnets (%d) to be allocated from it", gc.Auto.SubnetLen, gc.Auto.AllocSubnetLen) } return err }
// Allocate allocates a new resource. func (r *AutoVXLANCfgResource) Allocate() (interface{}, error) { oper := &AutoVXLANOperResource{} oper.StateDriver = r.StateDriver err := oper.Read(r.ID) if err != nil { return nil, err } vxlan, ok := oper.FreeVXLANs.NextSet(0) if !ok { return nil, core.Errorf("no vxlans available.") } vlan, ok := oper.FreeLocalVLANs.NextSet(0) if !ok { return nil, core.Errorf("no local vlans available.") } oper.FreeVXLANs.Clear(vxlan) oper.FreeLocalVLANs.Clear(vlan) err = oper.Write() if err != nil { return nil, err } return VXLANVLANPair{VXLAN: vxlan, VLAN: vlan}, nil }
// PolicyCreate creates policy func (ac *APIController) PolicyCreate(policy *contivModel.Policy) error { log.Infof("Received PolicyCreate: %+v", policy) // Make sure tenant exists if policy.TenantName == "" { return core.Errorf("Invalid tenant name") } tenant := contivModel.FindTenant(policy.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Setup links modeldb.AddLink(&policy.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.Policies, policy) // Save the tenant too since we added the links err := tenant.Write() if err != nil { log.Errorf("Error updating tenant state(%+v). Err: %v", tenant, err) return err } return nil }
// VolumeCreate creates a volume func (ac *APIController) VolumeCreate(volume *contivModel.Volume) error { log.Infof("Received VolumeCreate: %+v", volume) // Make sure tenant exists if volume.TenantName == "" { return core.Errorf("Invalid tenant name") } tenant := contivModel.FindTenant(volume.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Setup links modeldb.AddLink(&volume.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.Volumes, volume) // Save the tenant too since we added the links err := tenant.Write() if err != nil { return err } return nil }
// ServiceInstanceCreate creates a service instance func (ac *APIController) ServiceInstanceCreate(serviceInstance *contivModel.ServiceInstance) error { log.Infof("Received ServiceInstanceCreate: %+v", serviceInstance) inst := serviceInstance // Find the service serviceKey := inst.TenantName + ":" + inst.AppName + ":" + inst.ServiceName service := contivModel.FindService(serviceKey) if service == nil { log.Errorf("Service %s not found for instance: %+v", serviceKey, inst) return core.Errorf("Service not found") } // Add links modeldb.AddLinkSet(&service.LinkSets.Instances, inst) modeldb.AddLink(&inst.Links.Service, service) // setup links with volumes for _, volumeName := range inst.Volumes { // find the volume volume := contivModel.FindVolume(inst.TenantName + ":" + volumeName) if volume == nil { log.Errorf("Could not find colume %s for service: %s", volumeName, inst.Key) return core.Errorf("Could not find the volume") } // add Links modeldb.AddLinkSet(&inst.LinkSets.Volumes, volume) modeldb.AddLinkSet(&volume.LinkSets.ServiceInstances, inst) } return nil }
// Init initializes the OVS driver. func (d *OvsDriver) Init(config *core.Config, info *core.InstanceInfo) error { if config == nil || info == nil || info.StateDriver == nil { return core.Errorf("Invalid arguments. cfg: %+v, instance-info: %+v", config, info) } _, ok := config.V.(*OvsDriverConfig) if !ok { return core.Errorf("Invalid type passed") } d.oper.StateDriver = info.StateDriver d.localIP = info.VtepIP // restore the driver's runtime state if it exists err := d.oper.Read(info.HostLabel) if core.ErrIfKeyExists(err) != nil { log.Printf("Failed to read driver oper state for key %q. Error: %s", info.HostLabel, err) return err } else if err != nil { // create the oper state as it is first time start up d.oper.ID = info.HostLabel d.oper.CurrPortNum = 0 err = d.oper.Write() if err != nil { return err } } log.Infof("Initializing ovsdriver") // Init switch DB d.switchDb = make(map[string]*OvsSwitch) // Create Vxlan switch d.switchDb["vxlan"], err = NewOvsSwitch(vxlanBridgeName, "vxlan", info.VtepIP, info.FwdMode) if err != nil { log.Fatalf("Error creating vlan switch. Err: %v", err) } // Create Vlan switch d.switchDb["vlan"], err = NewOvsSwitch(vlanBridgeName, "vlan", info.VtepIP, info.FwdMode, info.VlanIntf) if err != nil { log.Fatalf("Error creating vlan switch. Err: %v", err) } // Add uplink to VLAN switch if info.VlanIntf != "" { err = d.switchDb["vlan"].AddUplinkPort(info.VlanIntf) if err != nil { log.Errorf("Could not add uplink %s to vlan OVS. Err: %v", info.VlanIntf, err) } } return nil }
// NetworkCreate creates network func (ac *APIController) NetworkCreate(network *contivModel.Network) error { log.Infof("Received NetworkCreate: %+v", network) // Make sure tenant exists if network.TenantName == "" { return core.Errorf("Invalid tenant name") } tenant := contivModel.FindTenant(network.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // If there is an EndpointGroup with the same name as this network, reject. nameClash := contivModel.FindEndpointGroup(network.Key) if nameClash != nil { return core.Errorf("EndpointGroup %s conflicts with the network name", nameClash.GroupName) } // Get the state driver stateDriver, err := utils.GetStateDriver() if err != nil { return err } // Build network config networkCfg := intent.ConfigNetwork{ Name: network.NetworkName, NwType: network.NwType, PktTagType: network.Encap, PktTag: network.PktTag, SubnetCIDR: network.Subnet, Gateway: network.Gateway, } // Create the network err = master.CreateNetwork(networkCfg, stateDriver, network.TenantName) if err != nil { log.Errorf("Error creating network {%+v}. Err: %v", network, err) return err } // Setup links modeldb.AddLink(&network.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.Networks, network) // Save the tenant too since we added the links err = tenant.Write() if err != nil { log.Errorf("Error updating tenant state(%+v). Err: %v", tenant, err) return err } return nil }
func validateHostConfig(host *intent.ConfigHost) error { if host.Name == "" { return core.Errorf("null host name") } if host.VtepIP == "" && host.Intf == "" { return core.Errorf("either vtep or intf needed for the host") } return nil }
// AppProfileUpdate updates app func (ac *APIController) AppProfileUpdate(oldProf, newProf *contivModel.AppProfile) error { log.Infof("Received AppProfileUpdate: %+v, newProf: %+v", oldProf, newProf) // handle any epg addition for _, epg := range newProf.EndpointGroups { epgKey := newProf.TenantName + ":" + epg log.Infof("Add %s to %s", epgKey, newProf.AppProfileName) epgObj := contivModel.FindEndpointGroup(epgKey) if epgObj == nil { return core.Errorf("EndpointGroup %s not found", epgKey) } modeldb.AddLinkSet(&newProf.LinkSets.EndpointGroups, epgObj) // workaround for objdb update problem modeldb.AddLinkSet(&oldProf.LinkSets.EndpointGroups, epgObj) modeldb.AddLink(&epgObj.Links.AppProfile, newProf) err := epgObj.Write() if err != nil { log.Errorf("Error updating epg state(%+v). Err: %v", epgObj, err) return err } } // handle any epg removal for _, epg := range oldProf.EndpointGroups { if !stringInSlice(epg, newProf.EndpointGroups) { epgKey := newProf.TenantName + ":" + epg log.Infof("Remove %s from %s", epgKey, newProf.AppProfileName) epgObj := contivModel.FindEndpointGroup(epgKey) if epgObj == nil { return core.Errorf("EndpointGroup %s not found", epgKey) } modeldb.RemoveLink(&epgObj.Links.AppProfile, oldProf) err := epgObj.Write() if err != nil { log.Errorf("Error updating epg state(%+v). Err: %v", epgObj, err) return err } // workaround for objdb update problem modeldb.RemoveLinkSet(&oldProf.LinkSets.EndpointGroups, epgObj) } } // workaround for objdb update problem -- should fix model oldProf.EndpointGroups = newProf.EndpointGroups // update the app nw DeleteAppNw(oldProf) CreateAppNw(oldProf) return nil }
// GetNextIPv6HostID returns the next available hostId in the AllocMap func GetNextIPv6HostID(hostID, subnetAddr string, subnetLen uint, IPv6AllocMap map[string]bool) (string, error) { if hostID == "" { hostID = "::" } if subnetLen == 0 { return "", core.Errorf("subnet length %d is invalid", subnetLen) } hostidIP := net.ParseIP(hostID) // start with the carryOver 1 to get the next hostID var carryOver = 1 var allocd = true for allocd == true { // Add 1 to hostID for i := len(hostidIP) - 1; i >= 0; i-- { var temp int temp = int(hostidIP[i]) + carryOver if temp > int(0xFF) { hostidIP[i] = 0 carryOver = 1 } else { hostidIP[i] = uint8(temp) carryOver = 0 break } } // Check if this hostID is already allocated if _, allocd = IPv6AllocMap[hostidIP.String()]; allocd == true { // Already allocated find the next hostID carryOver = 1 } else { // allocd == false. check if we reached MaxHosts offset := (subnetLen - 1) / 8 masklen := subnetLen % 8 mask := ((1 << masklen) - 1) << (8 - masklen) if (hostidIP[offset] & byte(mask)) != 0 { // if hostID is outside subnet range, // check if we have reached MaxHosts maxHosts := math.Pow(2, float64(128-subnetLen)) - 1 if float64(len(IPv6AllocMap)) < maxHosts { hostID = "::" hostidIP = net.ParseIP(hostID) carryOver = 1 allocd = true // continue the loop } else { return "", core.Errorf("Reached MaxHosts (%v). Cannot allocate more hosts", maxHosts) } } } } return hostidIP.String(), nil }
//ServiceLBCreate creates service object func (ac *APIController) ServiceLBCreate(serviceCfg *contivModel.ServiceLB) error { log.Infof("Received Service Load Balancer create: %+v", serviceCfg) if serviceCfg.ServiceName == "" { return core.Errorf("Invalid service name") } if serviceCfg.TenantName == "" { serviceCfg.TenantName = "default" } if len(serviceCfg.Selectors) == 0 { return core.Errorf("Invalid selector options") } if !validatePorts(serviceCfg.Ports) { return core.Errorf("Invalid Port maping . Port format is - Port:TargetPort:Protocol") } // Get the state driver stateDriver, err := utils.GetStateDriver() if err != nil { return err } // Build service config serviceIntentCfg := intent.ConfigServiceLB{ ServiceName: serviceCfg.ServiceName, Tenant: serviceCfg.TenantName, Network: serviceCfg.NetworkName, IPAddress: serviceCfg.IpAddress, } serviceIntentCfg.Ports = append(serviceIntentCfg.Ports, serviceCfg.Ports...) serviceIntentCfg.Selectors = make(map[string]string) for _, selector := range serviceCfg.Selectors { if validateSelectors(selector) { key := strings.Split(selector, "=")[0] value := strings.Split(selector, "=")[1] serviceIntentCfg.Selectors[key] = value } else { return core.Errorf("Invalid selector %s. selector format is key1=value1", selector) } } // Add the service object err = master.CreateServiceLB(stateDriver, &serviceIntentCfg) if err != nil { log.Errorf("Error creating service {%+v}. Err: %v", serviceIntentCfg.ServiceName, err) return err } return nil }
func validateEpBindings(epBindings *[]intent.ConfigEP) error { for _, ep := range *epBindings { if ep.Host == "" { return core.Errorf("invalid host name for the endpoint") } if ep.Container == "" { return core.Errorf("invalid container name for the endpoint") } } return nil }
// EndpointGroupCreate creates end point group func (ac *APIController) EndpointGroupCreate(endpointGroup *contivModel.EndpointGroup) error { log.Infof("Received EndpointGroupCreate: %+v", endpointGroup) // assign unique endpoint group ids endpointGroup.EndpointGroupID = globalEpgID globalEpgID = globalEpgID + 1 // Find the tenant tenant := contivModel.FindTenant(endpointGroup.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Setup links modeldb.AddLink(&endpointGroup.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.EndpointGroups, endpointGroup) // Save the tenant too since we added the links err := tenant.Write() if err != nil { return err } // for each policy create an epg policy Instance for _, policyName := range endpointGroup.Policies { policyKey := endpointGroup.TenantName + ":" + policyName // find the policy policy := contivModel.FindPolicy(policyKey) if policy == nil { log.Errorf("Could not find policy %s", policyName) return core.Errorf("Policy not found") } // attach policy to epg err = master.PolicyAttach(endpointGroup, policy) if err != nil { log.Errorf("Error attaching policy %s to epg %s", policyName, endpointGroup.Key) return err } // establish Links modeldb.AddLinkSet(&policy.LinkSets.EndpointGroups, endpointGroup) modeldb.AddLinkSet(&endpointGroup.LinkSets.Policies, policy) // Write the policy err = policy.Write() if err != nil { return err } } return nil }
// Setup brings up a vagrant testbed func (v *Vagrant) Setup(env string, numNodes int) error { vCmd := &VagrantCommand{ContivNodes: numNodes, ContivEnv: env} output, err := vCmd.RunWithOutput("up") if err != nil { log.Errorf("Vagrant up failed. Error: %s Output: \n%s\n", err, output) return err } v.expectedNodes = numNodes defer func() { if err != nil { v.Teardown() } }() output, err = vCmd.RunWithOutput("status") if err != nil { log.Errorf("Vagrant status failed. Error: %s Output: \n%s\n", err, output) return err } // now some hardwork of finding the names of the running nodes from status output re, err := regexp.Compile("[a-zA-Z0-9_\\- ]*running \\(virtualbox\\)") if err != nil { return err } nodeNamesBytes := re.FindAll(output, -1) if nodeNamesBytes == nil { err = core.Errorf("No running nodes found in vagrant status output: \n%s\n", output) return err } nodeNames := []string{} for _, nodeNameByte := range nodeNamesBytes { nodeName := strings.Fields(string(nodeNameByte))[0] nodeNames = append(nodeNames, nodeName) } if len(nodeNames) != numNodes { err = core.Errorf("Number of running node(s) (%d) is not equal to number of expected node(s) (%d) in vagrant status output: \n%s\n", len(nodeNames), numNodes, output) return err } // got the names, now fill up the vagrant-nodes structure for i, nodeName := range nodeNames { log.Infof("Adding node: %q", nodeName) node := TestbedNode(VagrantNode{Name: nodeName, NodeNum: i + 1}) v.nodes = append(v.nodes, node) } return nil }
// ParseCIDR parses a CIDR string into a gateway IP and length. func ParseCIDR(cidrStr string) (string, uint, error) { strs := strings.Split(cidrStr, "/") if len(strs) != 2 { return "", 0, core.Errorf("invalid cidr format") } subnetStr := strs[0] subnetLen, err := strconv.Atoi(strs[1]) if (IsIPv6(subnetStr) && subnetLen > 128) || err != nil || (!IsIPv6(subnetStr) && subnetLen > 32) { return "", 0, core.Errorf("invalid mask in gateway/mask specification ") } return subnetStr, uint(subnetLen), nil }
// Init the driver with a core.Config. func (d *EtcdStateDriver) Init(config *core.Config) error { if config == nil { return core.Errorf("Invalid arguments. cfg: %v", config) } cfg, ok := config.V.(*EtcdStateDriverConfig) if !ok { return core.Errorf("Invalid config type passed!") } d.Client = etcd.NewClient(cfg.Etcd.Machines) return nil }
// ValidateNetworkRangeParams verifies the network range format func ValidateNetworkRangeParams(ipRange string, subnetLen uint) error { rangeMin, _ := ipv4ToUint32(getFirstAddrInRange(ipRange)) rangeMax, _ := ipv4ToUint32(getLastAddrInRange(ipRange, subnetLen)) firstAddr, _ := ipv4ToUint32(GetSubnetAddr(ipRange, subnetLen)) lastAddr, _ := ipv4ToUint32(getLastAddrInSubnet(ipRange, subnetLen)) if rangeMin < firstAddr || rangeMax > lastAddr || rangeMin > rangeMax { return core.Errorf("Network subnet format not valid") } if subnetLen > 32 || subnetLen < 8 { return core.Errorf("subnet length %d not supported", subnetLen) } return nil }
// NetworkCreate creates network func (ac *APIController) NetworkCreate(network *contivModel.Network) error { log.Infof("Received NetworkCreate: %+v", network) // Make sure tenant exists if network.TenantName == "" { return core.Errorf("Invalid tenant name") } tenant := contivModel.FindTenant(network.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Setup links modeldb.AddLink(&network.Links.Tenant, tenant) modeldb.AddLinkSet(&tenant.LinkSets.Networks, network) // Save the tenant too since we added the links err := tenant.Write() if err != nil { log.Errorf("Error updating tenant state(%+v). Err: %v", tenant, err) return err } // Get the state driver stateDriver, err := utils.GetStateDriver() if err != nil { return err } // Build networ config networkCfg := intent.ConfigNetwork{ Name: network.NetworkName, PktTagType: network.Encap, PktTag: "", SubnetCIDR: network.Subnet, DefaultGw: network.DefaultGw, } // Create the network err = master.CreateNetwork(networkCfg, stateDriver, network.TenantName) if err != nil { log.Errorf("Error creating network {%+v}. Err: %v", network, err) return err } return nil }
// Init the resource. func (r *AutoVXLANCfgResource) Init(rsrcCfg interface{}) error { cfg, ok := rsrcCfg.(*AutoVXLANCfgResource) if !ok { return core.Errorf("Invalid vxlan resource config.") } r.VXLANs = cfg.VXLANs r.LocalVLANs = cfg.LocalVLANs err := r.Write() if err != nil { return err } defer func() { if err != nil { r.Clear() } }() oper := &AutoVXLANOperResource{FreeVXLANs: r.VXLANs, FreeLocalVLANs: r.LocalVLANs} oper.StateDriver = r.StateDriver oper.ID = r.ID err = oper.Write() if err != nil { return err } return nil }