func (tenantStore *tenantStore) addTenant(tenant *Tenant) error { // log.Println("In tenantStore addTenant()") log.Printf("In tenantStore addTenant(%v) in %s", *tenant, tenantStore.Config.Database) var tenants []Tenant tx := tenantStore.DbStore.Db.Begin() err := common.GetDbErrors(tx) if err != nil { tx.Rollback() return err } tx = tx.Find(&tenants) err = common.GetDbErrors(tx) if err != nil { tx.Rollback() return err } tenant.NetworkID = uint64(len(tenants)) tx = tx.Create(tenant) err = common.GetDbErrors(tx) if err != nil { tx.Rollback() return err } tx.Commit() return nil }
func (agentStore *agentStore) deleteNetIf(netif *NetIf) error { db := agentStore.DbStore.Db agentStore.DbStore.Db.Delete(netif) err := common.GetDbErrors(db) if err != nil { return err } return nil }
func (agentStore *agentStore) listNetIfs() ([]NetIf, error) { db := agentStore.DbStore.Db var netifs []NetIf agentStore.DbStore.Db.Find(&netifs) err := common.GetDbErrors(db) if err != nil { return nil, err } return netifs, nil }
// CreateSchemaPostProcess implements CreateSchemaPostProcess method of // ServiceStore interface. func (tenantStore *tenantStore) CreateSchemaPostProcess() error { db := tenantStore.Db log.Printf("tenantStore.CreateSchemaPostProcess(), DB is %v", db) db.Model(&Tenant{}).AddUniqueIndex("idx_extid", "external_id") // This should be changed... db.Model(&Segment{}).AddUniqueIndex("idx_tenant_name_extid", "tenant_id", "name", "external_id") err := common.GetDbErrors(db) if err != nil { return err } return nil }
func (agentStore *agentStore) findNetIf(netif *NetIf) error { db := agentStore.DbStore.Db var count int agentStore.DbStore.Db.Where(netif).First(netif).Count(&count) err := common.GetDbErrors(db) if err != nil { return err } if count == 0 { return common.NewError404("interface", fmt.Sprintf("mac: %s", netif.Mac)) } return nil }
func (tenantStore *tenantStore) getTenant(id string) (Tenant, error) { ten := Tenant{} var count int log.Println("In getTenant()") db := tenantStore.DbStore.Db.Where("id = ?", id).First(&ten).Count(&count) err := common.GetDbErrors(db) if err != nil { return ten, err } if count == 0 { return ten, common.NewError404("tenant", id) } return ten, nil }
func (tenantStore *tenantStore) getSegment(tenantId string, segmentId string) (Segment, error) { seg := Segment{} var count int db := tenantStore.DbStore.Db.Where("tenant_id = ? AND id = ?", tenantId, segmentId). First(&seg).Count(&count) err := common.GetDbErrors(db) if err != nil { return seg, err } if count == 0 { return seg, common.NewError404("segment/tenant", fmt.Sprintf("%s/%s", tenantId, segmentId)) } return seg, nil }
func (tenantStore *tenantStore) addSegment(tenantId uint64, segment *Segment) error { var err error tx := tenantStore.DbStore.Db.Begin() var segments []Segment tx = tx.Where("tenant_id = ?", tenantId).Find(&segments) err = common.GetDbErrors(tx) if err != nil { tx.Rollback() return err } segment.NetworkID = uint64(len(segments)) segment.TenantID = tenantId tx = tx.Create(segment) err = common.GetDbErrors(tx) if err != nil { tx.Rollback() return err } tx.Commit() return nil }
// addEndpoint allocates an IP address and stores it in the // database. func (ipamStore *ipamStore) addEndpoint(endpoint *Endpoint, upToEndpointIpInt uint64, dc common.Datacenter) error { var err error tx := ipamStore.DbStore.Db.Begin() if endpoint.RequestToken.Valid && endpoint.RequestToken.String != "" { var existingEndpoints []Endpoint var count int tx.Where("request_token = ?", endpoint.RequestToken.String).Find(&existingEndpoints).Count(&count) err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 1: %v", err) tx.Rollback() return err } if count > 0 { // This will only be 1, because of unique constraint. tx.Rollback() log.Printf("Found existing %s: %+v", endpoint.RequestToken.String, existingEndpoints[0]) endpoint.EffectiveNetworkID = existingEndpoints[0].EffectiveNetworkID endpoint.HostId = existingEndpoints[0].HostId endpoint.Id = existingEndpoints[0].Id endpoint.InUse = existingEndpoints[0].InUse endpoint.Name = existingEndpoints[0].Name endpoint.NetworkID = existingEndpoints[0].NetworkID endpoint.RequestToken = existingEndpoints[0].RequestToken endpoint.SegmentID = existingEndpoints[0].SegmentID endpoint.TenantID = existingEndpoints[0].TenantID endpoint.Ip = existingEndpoints[0].Ip return nil } } hostId := endpoint.HostId endpoint.InUse = true tenantId := endpoint.TenantID segId := endpoint.SegmentID filter := "host_id = ? AND tenant_id = ? AND segment_id = ? " var sel string // First, find the MAX network ID available for this host/segment combination. sel = "IFNULL(MAX(network_id),-1)+1" log.Printf("IpamStore: Calling SELECT %s FROM endpoints WHERE %s;", sel, fmt.Sprintf(strings.Replace(filter, "?", "%s", 3), hostId, tenantId, segId)) row := tx.Model(Endpoint{}).Where(filter, hostId, tenantId, segId).Select(sel).Row() err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 2: %v", err) tx.Rollback() return err } netID := sql.NullInt64{} row.Scan(&netID) err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 3: %v", err) tx.Rollback() return err } log.Printf("IpamStore: max net ID: %v", netID) maxEffNetID := uint64(1<<(dc.EndpointSpaceBits+dc.EndpointBits) - 1) // Does this exceed max bits? endpoint.NetworkID = uint64(netID.Int64) endpoint.EffectiveNetworkID = getEffectiveNetworkID(endpoint.NetworkID, dc.EndpointSpaceBits) if endpoint.EffectiveNetworkID <= maxEffNetID { // Does not exceed max bits, all good. // log.Printf("IpamStore: Effective network ID for network ID %d (stride %d): %d\n", endpoint.NetworkID, dc.EndpointSpaceBits, endpoint.EffectiveNetworkID) ipInt := upToEndpointIpInt | endpoint.EffectiveNetworkID // log.Printf("IpamStore: %d | %d = %d", upToEndpointIpInt, endpoint.EffectiveNetworkID, ipInt) endpoint.Ip = common.IntToIPv4(ipInt).String() tx = tx.Create(endpoint) err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 4: %v", err) tx.Rollback() return err } log.Printf("IpamStore: Allocated %d: %s", endpoint.NetworkID, endpoint.Ip) tx.Commit() return nil } // Out of bits, see if we can reuse an earlier allocated address... log.Printf("IpamStore: New effective network ID is %d, exceeds maximum %d\n", endpoint.EffectiveNetworkID, maxEffNetID) // See if there is a formerly allocated IP already that has been released // (marked "in_use") sel = "MIN(network_id), ip" log.Printf("IpamStore: Calling SELECT %s FROM endpoints WHERE %s;", sel, fmt.Sprintf(strings.Replace(filter+"AND in_use = 0", "?", "%s", 3), hostId, tenantId, segId)) // In containerized setup, not using group by leads to failure due to // incompatible sql mode, thus use "GROUP BY network_id, ip" to avoid // this failure. row = tx.Model(Endpoint{}).Where(filter+"AND in_use = 0", hostId, tenantId, segId).Select(sel).Group("ip").Order("MIN(network_id) ASC").Row() err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 5: %v", err) tx.Rollback() return err } netID = sql.NullInt64{} var ip string row.Scan(&netID, &ip) err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 6: %v", err) tx.Rollback() return err } if netID.Valid { log.Printf("IpamStore: Reusing %d: %s", netID.Int64, ip) endpoint.Ip = ip tx = tx.Model(Endpoint{}).Where("ip = ?", ip).Update("in_use", true) err = common.GetDbErrors(tx) if err != nil { log.Printf("IPAM Errors 7: %v", err) tx.Rollback() return err } tx.Commit() return nil } tx.Rollback() return common.NewError("Out of IP addresses.") }