예제 #1
0
파일: store.go 프로젝트: romana/core
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
}
예제 #2
0
파일: store.go 프로젝트: romana/core
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
}
예제 #3
0
파일: store.go 프로젝트: romana/core
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
}
예제 #4
0
파일: store.go 프로젝트: romana/core
// 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
}
예제 #5
0
파일: store.go 프로젝트: romana/core
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
}
예제 #6
0
파일: store.go 프로젝트: romana/core
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
}
예제 #7
0
파일: store.go 프로젝트: romana/core
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
}
예제 #8
0
파일: store.go 프로젝트: romana/core
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
}
예제 #9
0
파일: store.go 프로젝트: romana/core
// 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.")

}