// getEndpointGroupID returns endpoint group Id for a service // It autocreates the endpoint group if it doesnt exist func getEndpointGroupID(serviceName, networkName string) (int, error) { // FIXME: Get tenant name tenantName := "default" // If service name is not specified, we are done if serviceName == "" { return 0, nil } // form the key based on network and service name. epgName := serviceName + "." + networkName epgKey := tenantName + ":" + epgName // See if the epg exists epg := contivModel.FindEndpointGroup(epgKey) if epg == nil { endpointGroup := contivModel.EndpointGroup{ Key: epgKey, TenantName: tenantName, NetworkName: networkName, GroupName: epgName, } // Create endpoint group err := contivModel.CreateEndpointGroup(&endpointGroup) if err != nil { log.Errorf("Error creating endpoint group: %+v, Err: %v", endpointGroup, err) return 0, err } // find again epg = contivModel.FindEndpointGroup(epgKey) if epg == nil { log.Errorf("Error creating endpoint group %s.", epgName) return 0, core.Errorf("EPG not created") } } // return endpoint group id return epg.EndpointGroupID, nil }
// getEndpointGroupID returns endpoint group Id for a service // It autocreates the endpoint group if it doesnt exist func getEndpointGroupID(serviceName, networkName, tenantName string) (int, error) { // If service name is not specified, we are done if serviceName == "" { // FIXME: Need a better way to handle default epg for the network return 0, nil } // form the key based on network and service name. epgKey := tenantName + ":" + networkName + ":" + serviceName // See if the epg exists epg := contivModel.FindEndpointGroup(epgKey) if epg == nil { return 0, core.Errorf("EPG not created") } // return endpoint group id return epg.EndpointGroupID, nil }
// ServiceCreate creates service func (ac *APIController) ServiceCreate(service *contivModel.Service) error { log.Infof("Received ServiceCreate: %+v", service) // check params if (service.TenantName == "") || (service.AppName == "") { return core.Errorf("Invalid parameters") } // Make sure tenant exists tenant := contivModel.FindTenant(service.TenantName) if tenant == nil { return core.Errorf("Tenant not found") } // Find the app this service belongs to app := contivModel.FindApp(service.TenantName + ":" + service.AppName) if app == nil { return core.Errorf("App not found") } // Setup links modeldb.AddLink(&service.Links.App, app) modeldb.AddLinkSet(&app.LinkSets.Services, service) // Save the app too since we added the links err := app.Write() if err != nil { return err } // Check if user specified any networks if len(service.Networks) == 0 { service.Networks = append(service.Networks, "private") } // link service with network for _, netName := range service.Networks { netKey := service.TenantName + ":" + netName network := contivModel.FindNetwork(netKey) if network == nil { log.Errorf("Service: %s could not find network %s", service.Key, netKey) return core.Errorf("Network not found") } // Link the network modeldb.AddLinkSet(&service.LinkSets.Networks, network) modeldb.AddLinkSet(&network.LinkSets.Services, service) // save the network err := network.Write() if err != nil { return err } } // Check if user specified any endpoint group for the service if len(service.EndpointGroups) == 0 { // Create one default endpointGroup per network for _, netName := range service.Networks { // params for default endpoint group dfltEpgName := service.AppName + "." + service.ServiceName + "." + netName endpointGroup := contivModel.EndpointGroup{ Key: service.TenantName + ":" + dfltEpgName, TenantName: service.TenantName, NetworkName: netName, GroupName: dfltEpgName, } // Create default endpoint group for the service err = contivModel.CreateEndpointGroup(&endpointGroup) if err != nil { log.Errorf("Error creating endpoint group: %+v, Err: %v", endpointGroup, err) return err } // Add the endpoint group to the list service.EndpointGroups = append(service.EndpointGroups, dfltEpgName) } } // Link the service and endpoint group for _, epgName := range service.EndpointGroups { endpointGroup := contivModel.FindEndpointGroup(service.TenantName + ":" + epgName) if endpointGroup == nil { log.Errorf("Error: could not find endpoint group: %s", epgName) return core.Errorf("could not find endpointGroup") } // setup links modeldb.AddLinkSet(&service.LinkSets.EndpointGroups, endpointGroup) modeldb.AddLinkSet(&endpointGroup.LinkSets.Services, service) // save the endpointGroup err = endpointGroup.Write() if err != nil { return err } } return nil }
//CreateAppNw Fill in the Nw spec and launch the nw infra func CreateAppNw(app *contivModel.App) error { aciPresent, aErr := master.IsAciConfigured() if aErr != nil { log.Errorf("Couldn't read global config %v", aErr) return aErr } if !aciPresent { log.Debugf("ACI not configured") return nil } // Get the state driver stateDriver, uErr := utils.GetStateDriver() if uErr != nil { return uErr } netName := "" eMap := &epgMap{} eMap.Specs = make(map[string]epgSpec) ans := &appNwSpec{} ans.TenantName = app.TenantName ans.AppName = app.AppName // Gather all basic epg info into the epg map for epgKey := range app.LinkSets.Services { epgObj := contivModel.FindEndpointGroup(epgKey) if epgObj == nil { err := fmt.Sprintf("Epg %v does not exist", epgKey) log.Errorf("%v", err) return errors.New(err) } if err := appendEpgInfo(eMap, epgObj, stateDriver); err != nil { log.Errorf("Error getting epg info %v", err) return err } netName = epgObj.NetworkName } // walk the map and add to ANS for _, epg := range eMap.Specs { ans.Epgs = append(ans.Epgs, epg) log.Debugf("Added epg %v", epg.Name) } // get the subnet info and add it to ans nwCfg := &mastercfg.CfgNetworkState{} nwCfg.StateDriver = stateDriver networkID := netName + "." + app.TenantName nErr := nwCfg.Read(networkID) if nErr != nil { log.Errorf("Failed to network info %v %v ", netName, nErr) return nErr } ans.Subnet = nwCfg.Gateway + "/" + strconv.Itoa(int(nwCfg.SubnetLen)) log.Debugf("Nw %v subnet %v", netName, ans.Subnet) ans.launch() return nil }
// createOfnetRule creates a directional ofnet rule func (gp *EpgPolicy) createOfnetRule(rule *contivModel.Rule, dir string) (*ofnet.OfnetPolicyRule, error) { ruleID := gp.EpgPolicyKey + ":" + rule.Key + ":" + dir // Create an ofnet rule ofnetRule := new(ofnet.OfnetPolicyRule) ofnetRule.RuleId = ruleID ofnetRule.Priority = rule.Priority ofnetRule.Action = rule.Action remoteEpgID := 0 // See if user specified an endpoint Group in the rule if rule.EndpointGroup != "" { epgKey := rule.TenantName + ":" + rule.EndpointGroup // find the endpoint group epg := contivModel.FindEndpointGroup(epgKey) if epg == nil { log.Errorf("Error finding endpoint group %s", epgKey) return nil, core.Errorf("endpoint group not found") } remoteEpgID = epg.EndpointGroupID } // Set protocol switch rule.Protocol { case "tcp": ofnetRule.IpProtocol = 6 case "udp": ofnetRule.IpProtocol = 17 case "icmp": ofnetRule.IpProtocol = 1 case "igmp": ofnetRule.IpProtocol = 2 case "": ofnetRule.IpProtocol = 0 default: proto, err := strconv.Atoi(rule.Protocol) if err == nil && proto < 256 { ofnetRule.IpProtocol = uint8(proto) } } // Set directional parameters switch dir { case "inRx": // Set src/dest endpoint group ofnetRule.DstEndpointGroup = gp.EndpointGroupID ofnetRule.SrcEndpointGroup = remoteEpgID // Set src/dest IP Address ofnetRule.SrcIpAddr = rule.IpAddress // set port numbers ofnetRule.DstPort = uint16(rule.Port) // set tcp flags if rule.Protocol == "tcp" && rule.Port == 0 { ofnetRule.TcpFlags = "syn,!ack" } case "inTx": // Set src/dest endpoint group ofnetRule.SrcEndpointGroup = gp.EndpointGroupID ofnetRule.DstEndpointGroup = remoteEpgID // Set src/dest IP Address ofnetRule.DstIpAddr = rule.IpAddress // set port numbers ofnetRule.SrcPort = uint16(rule.Port) case "outRx": // Set src/dest endpoint group ofnetRule.DstEndpointGroup = gp.EndpointGroupID ofnetRule.SrcEndpointGroup = remoteEpgID // Set src/dest IP Address ofnetRule.SrcIpAddr = rule.IpAddress // set port numbers ofnetRule.SrcPort = uint16(rule.Port) case "outTx": // Set src/dest endpoint group ofnetRule.SrcEndpointGroup = gp.EndpointGroupID ofnetRule.DstEndpointGroup = remoteEpgID // Set src/dest IP Address ofnetRule.DstIpAddr = rule.IpAddress // set port numbers ofnetRule.DstPort = uint16(rule.Port) // set tcp flags if rule.Protocol == "tcp" && rule.Port == 0 { ofnetRule.TcpFlags = "syn,!ack" } default: log.Fatalf("Unknown rule direction %s", dir) } // Add the Rule to policyDB err := ofnetMaster.AddRule(ofnetRule) if err != nil { log.Errorf("Error creating rule {%+v}. Err: %v", ofnetRule, err) return nil, err } log.Infof("Added rule {%+v} to policyDB", ofnetRule) return ofnetRule, nil }
// ServiceCreate creates service func (ac *APIController) ServiceCreate(service *contivModel.Service) error { log.Infof("Received ServiceCreate: %+v", service) // check params if (service.TenantName == "") || (service.AppName == "") { return errors.New("Invalid parameters") } // Make sure tenant exists tenant := contivModel.FindTenant(service.TenantName) if tenant == nil { return errors.New("Tenant not found") } // Find the app this service belongs to app := contivModel.FindApp(service.TenantName + ":" + service.AppName) if app == nil { return errors.New("App not found") } // Setup links modeldb.AddLink(&service.Links.App, app) modeldb.AddLinkSet(&app.LinkSets.Services, service) // Save the app too since we added the links err := app.Write() if err != nil { return err } // Check if user specified any networks if len(service.Networks) == 0 { service.Networks = append(service.Networks, "privateNet") } // link service with network for _, netName := range service.Networks { netKey := service.TenantName + ":" + netName network := contivModel.FindNetwork(netKey) if network == nil { log.Errorf("Service: %s could not find network %s", service.Key, netKey) return errors.New("Network not found") } // Link the network modeldb.AddLinkSet(&service.LinkSets.Networks, network) modeldb.AddLinkSet(&network.LinkSets.Services, service) // save the network err := network.Write() if err != nil { return err } } // Check if user specified any endpoint group for the service if len(service.EndpointGroups) == 0 { // Create one default endpointGroup per network for _, netName := range service.Networks { // params for default endpoint group dfltEpgName := service.AppName + "." + service.ServiceName + "." + netName endpointGroup := contivModel.EndpointGroup{ Key: service.TenantName + ":" + dfltEpgName, TenantName: service.TenantName, NetworkName: netName, GroupName: dfltEpgName, } // Create default endpoint group for the service err = contivModel.CreateEndpointGroup(&endpointGroup) if err != nil { log.Errorf("Error creating endpoint group: %+v, Err: %v", endpointGroup, err) return err } // Add the endpoint group to the list service.EndpointGroups = append(service.EndpointGroups, dfltEpgName) } } // Link the service and endpoint group for _, epgName := range service.EndpointGroups { endpointGroup := contivModel.FindEndpointGroup(service.TenantName + ":" + epgName) if endpointGroup == nil { log.Errorf("Error: could not find endpoint group: %s", epgName) return errors.New("could not find endpointGroup") } // setup links modeldb.AddLinkSet(&service.LinkSets.EndpointGroups, endpointGroup) modeldb.AddLinkSet(&endpointGroup.LinkSets.Services, service) // save the endpointGroup err = endpointGroup.Write() if err != nil { return err } } // Check if user specified any volume profile if service.VolumeProfile == "" { service.VolumeProfile = "default" } volProfKey := service.TenantName + ":" + service.VolumeProfile volProfile := contivModel.FindVolumeProfile(volProfKey) if volProfile == nil { log.Errorf("Could not find the volume profile: %s", service.VolumeProfile) return errors.New("VolumeProfile not found") } // fixup default values if service.Scale == 0 { service.Scale = 1 } // Create service instances for idx := int64(0); idx < service.Scale; idx++ { instID := fmt.Sprintf("%d", idx+1) var volumes []string // Create a volume for each instance based on the profile if volProfile.DatastoreType != "none" { instVolName := service.AppName + "." + service.ServiceName + "." + instID err = contivModel.CreateVolume(&contivModel.Volume{ Key: service.TenantName + ":" + instVolName, VolumeName: instVolName, TenantName: service.TenantName, DatastoreType: volProfile.DatastoreType, PoolName: volProfile.PoolName, Size: volProfile.Size, MountPoint: volProfile.MountPoint, }) if err != nil { log.Errorf("Error creating volume %s. Err: %v", instVolName, err) return err } volumes = []string{instVolName} } // build instance params instKey := service.TenantName + ":" + service.AppName + ":" + service.ServiceName + ":" + instID inst := contivModel.ServiceInstance{ Key: instKey, InstanceID: instID, TenantName: service.TenantName, AppName: service.AppName, ServiceName: service.ServiceName, Volumes: volumes, } // create the instance err := contivModel.CreateServiceInstance(&inst) if err != nil { log.Errorf("Error creating service instance: %+v. Err: %v", inst, err) return err } } return nil }