| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | package resources | 
					
						
							| 
									
										
										
										
											2024-07-18 11:51:12 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-15 10:56:44 +01:00
										 |  |  | 	"cloud.o-forge.io/core/oc-lib/models/common/enum" | 
					
						
							|  |  |  | 	"cloud.o-forge.io/core/oc-lib/models/common/models" | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	"cloud.o-forge.io/core/oc-lib/models/common/pricing" | 
					
						
							| 
									
										
										
										
											2024-07-18 13:35:14 +02:00
										 |  |  | 	"cloud.o-forge.io/core/oc-lib/models/utils" | 
					
						
							| 
									
										
										
										
											2024-08-12 16:11:25 +02:00
										 |  |  | 	"cloud.o-forge.io/core/oc-lib/tools" | 
					
						
							| 
									
										
										
										
											2024-07-18 11:51:12 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 14:50:48 +02:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2024-11-07 11:05:24 +01:00
										 |  |  | * ComputeResource is a struct that represents a compute resource | 
					
						
							|  |  |  | * it defines the resource compute | 
					
						
							| 
									
										
										
										
											2024-08-30 14:50:48 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-11-07 11:05:24 +01:00
										 |  |  | type ComputeResource struct { | 
					
						
							| 
									
										
										
										
											2025-02-13 15:11:23 +01:00
										 |  |  | 	AbstractInstanciatedResource[*ComputeResourceInstance] | 
					
						
							| 
									
										
										
										
											2025-01-15 10:56:44 +01:00
										 |  |  | 	Architecture   string                  `json:"architecture,omitempty" bson:"architecture,omitempty"` // Architecture is the architecture | 
					
						
							| 
									
										
										
										
											2025-01-17 10:07:37 +01:00
										 |  |  | 	Infrastructure enum.InfrastructureType `json:"infrastructure" bson:"infrastructure" default:"-1"`    // Infrastructure is the infrastructure | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-11-07 11:36:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | func (d *ComputeResource) GetAccessor(request *tools.APIRequest) utils.Accessor { | 
					
						
							|  |  |  | 	return NewAccessor[*ComputeResource](tools.COMPUTE_RESOURCE, request, func() utils.DBObject { return &ComputeResource{} }) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-11-07 11:36:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-20 13:26:30 +01:00
										 |  |  | func (r *ComputeResource) GetType() string { | 
					
						
							|  |  |  | 	return tools.COMPUTE_RESOURCE.String() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-15 09:20:26 +01:00
										 |  |  | func (abs *ComputeResource) ConvertToPricedResource( | 
					
						
							|  |  |  | 	t tools.DataType, request *tools.APIRequest) pricing.PricedItemITF { | 
					
						
							| 
									
										
										
										
											2025-01-15 10:56:44 +01:00
										 |  |  | 	if t != tools.COMPUTE_RESOURCE { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-13 15:11:23 +01:00
										 |  |  | 	p := abs.AbstractInstanciatedResource.ConvertToPricedResource(t, request) | 
					
						
							| 
									
										
										
										
											2025-01-15 09:20:26 +01:00
										 |  |  | 	priced := p.(*PricedResource) | 
					
						
							|  |  |  | 	return &PricedComputeResource{ | 
					
						
							|  |  |  | 		PricedResource: *priced, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-14 11:28:16 +01:00
										 |  |  | type ComputeNode struct { | 
					
						
							|  |  |  | 	Name     string           `json:"name,omitempty" bson:"name,omitempty"` | 
					
						
							|  |  |  | 	Quantity int64            `json:"quantity" bson:"quantity" default:"1"` | 
					
						
							| 
									
										
										
										
											2025-01-15 10:56:44 +01:00
										 |  |  | 	RAM      *models.RAM      `bson:"ram,omitempty" json:"ram,omitempty"`   // RAM is the RAM | 
					
						
							| 
									
										
										
										
											2025-01-14 11:28:16 +01:00
										 |  |  | 	CPUs     map[string]int64 `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs key is model | 
					
						
							|  |  |  | 	GPUs     map[string]int64 `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs key is model | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | type ComputeResourceInstance struct { | 
					
						
							|  |  |  | 	ResourceInstance[*ComputeResourcePartnership] | 
					
						
							| 
									
										
										
										
											2025-02-13 15:11:23 +01:00
										 |  |  | 	Source             string                 `json:"source,omitempty" bson:"source,omitempty"` // Source is the source of the resource | 
					
						
							| 
									
										
										
										
											2025-01-14 11:28:16 +01:00
										 |  |  | 	SecurityLevel      string                 `json:"security_level,omitempty" bson:"security_level,omitempty"` | 
					
						
							|  |  |  | 	PowerSources       []string               `json:"power_sources,omitempty" bson:"power_sources,omitempty"` | 
					
						
							|  |  |  | 	AnnualCO2Emissions float64                `json:"annual_co2_emissions,omitempty" bson:"co2_emissions,omitempty"` | 
					
						
							| 
									
										
										
										
											2025-01-15 10:56:44 +01:00
										 |  |  | 	CPUs               map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs key is model | 
					
						
							|  |  |  | 	GPUs               map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs key is model | 
					
						
							| 
									
										
										
										
											2025-01-14 11:28:16 +01:00
										 |  |  | 	Nodes              []*ComputeNode         `json:"nodes,omitempty" bson:"nodes,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-07-18 11:51:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | type ComputeResourcePartnership struct { | 
					
						
							| 
									
										
										
										
											2025-01-22 13:18:14 +01:00
										 |  |  | 	ResourcePartnerShip[*ComputeResourcePricingProfile] | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	MaxAllowedCPUsCores    map[string]int     `json:"allowed_cpus,omitempty" bson:"allowed_cpus,omitempty"` | 
					
						
							|  |  |  | 	MaxAllowedGPUsMemoryGB map[string]float64 `json:"allowed_gpus,omitempty" bson:"allowed_gpus,omitempty"` | 
					
						
							|  |  |  | 	MaxAllowedRAMSize      float64            `json:"allowed_ram,omitempty" bson:"allowed_ram,omitempty"` | 
					
						
							| 
									
										
										
										
											2024-07-18 11:51:12 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-07-26 15:19:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | type ComputeResourcePricingProfile struct { | 
					
						
							| 
									
										
										
										
											2024-12-16 12:17:20 +01:00
										 |  |  | 	pricing.ExploitPricingProfile[pricing.TimePricingStrategy] | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	// ExploitPricingProfile is the pricing profile of a compute it means that we exploit the resource for an amount of continuous time | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 	CPUsPrices map[string]float64 `json:"cpus_prices,omitempty" bson:"cpus_prices,omitempty"` // CPUsPrices is the prices of the CPUs | 
					
						
							|  |  |  | 	GPUsPrices map[string]float64 `json:"gpus_prices,omitempty" bson:"gpus_prices,omitempty"` // GPUsPrices is the prices of the GPUs | 
					
						
							|  |  |  | 	RAMPrice   float64            `json:"ram_price" bson:"ram_price" default:"-1"`            // RAMPrice is the price of the RAM | 
					
						
							| 
									
										
										
										
											2024-07-26 15:19:36 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-17 10:42:00 +01:00
										 |  |  | func (p *ComputeResourcePricingProfile) IsPurchased() bool { | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	return p.Pricing.BuyingStrategy != pricing.PAY_PER_USE | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | func (p *ComputeResourcePricingProfile) GetOverrideStrategyValue() int { | 
					
						
							|  |  |  | 	return -1 | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | // NOT A PROPER QUANTITY | 
					
						
							|  |  |  | // amountOfData is the number of CPUs, GPUs or RAM dependings on the params | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | func (p *ComputeResourcePricingProfile) GetPrice(amountOfData float64, explicitDuration float64, start time.Time, end time.Time, params ...string) (float64, error) { | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	if len(params) < 1 { | 
					
						
							|  |  |  | 		return 0, errors.New("params must be set") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	pp := float64(0) | 
					
						
							|  |  |  | 	model := params[1] | 
					
						
							|  |  |  | 	if strings.Contains(params[0], "cpus") && len(params) > 1 { | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		if _, ok := p.CPUsPrices[model]; ok { | 
					
						
							|  |  |  | 			p.Pricing.Price = p.CPUsPrices[model] | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		r, err := p.Pricing.GetPrice(amountOfData, explicitDuration, start, &end) | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		pp += r | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if strings.Contains(params[0], "gpus") && len(params) > 1 { | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		if _, ok := p.GPUsPrices[model]; ok { | 
					
						
							|  |  |  | 			p.Pricing.Price = p.GPUsPrices[model] | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		r, err := p.Pricing.GetPrice(amountOfData, explicitDuration, start, &end) | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		pp += r | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if strings.Contains(params[0], "ram") { | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		if p.RAMPrice >= 0 { | 
					
						
							|  |  |  | 			p.Pricing.Price = p.RAMPrice | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-01-16 15:14:56 +01:00
										 |  |  | 		r, err := p.Pricing.GetPrice(float64(amountOfData), explicitDuration, start, &end) | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return 0, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		pp += r | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return pp, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | type PricedComputeResource struct { | 
					
						
							|  |  |  | 	PricedResource | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	CPUsLocated map[string]float64 `json:"cpus_in_use" bson:"cpus_in_use"` // CPUsInUse is the list of CPUs in use | 
					
						
							|  |  |  | 	GPUsLocated map[string]float64 `json:"gpus_in_use" bson:"gpus_in_use"` // GPUsInUse is the list of GPUs in use | 
					
						
							|  |  |  | 	RAMLocated  float64            `json:"ram_in_use" bson:"ram_in_use"`   // RAMInUse is the RAM in use | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | func (r *PricedComputeResource) GetType() tools.DataType { | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	return tools.COMPUTE_RESOURCE | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | func (r *PricedComputeResource) GetPrice() (float64, error) { | 
					
						
							| 
									
										
										
										
											2025-02-10 13:04:13 +01:00
										 |  |  | 	now := time.Now() | 
					
						
							|  |  |  | 	if r.UsageStart == nil { | 
					
						
							|  |  |  | 		r.UsageStart = &now | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-10 13:04:13 +01:00
										 |  |  | 	if r.UsageEnd == nil { | 
					
						
							|  |  |  | 		add := r.UsageStart.Add(time.Duration(1 * time.Hour)) | 
					
						
							|  |  |  | 		r.UsageEnd = &add | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-10 13:10:42 +01:00
										 |  |  | 	if r.SelectedPricing == nil { | 
					
						
							| 
									
										
										
										
											2025-02-10 13:04:13 +01:00
										 |  |  | 		if len(r.PricingProfiles) == 0 { | 
					
						
							| 
									
										
										
										
											2025-02-11 09:16:18 +01:00
										 |  |  | 			return 0, errors.New("pricing profile must be set on Priced Compute" + r.ResourceID) | 
					
						
							| 
									
										
										
										
											2025-02-10 13:04:13 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-02-11 09:16:18 +01:00
										 |  |  | 		r.SelectedPricing = &r.PricingProfiles[0] | 
					
						
							| 
									
										
										
										
											2025-02-10 13:04:13 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-02-10 13:10:42 +01:00
										 |  |  | 	pricing := *r.SelectedPricing | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	price := float64(0) | 
					
						
							|  |  |  | 	for _, l := range []map[string]float64{r.CPUsLocated, r.GPUsLocated} { | 
					
						
							|  |  |  | 		for model, amountOfData := range l { | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | 			cpus, err := pricing.GetPrice(float64(amountOfData), r.ExplicitBookingDurationS, *r.UsageStart, *r.UsageEnd, "cpus", model) | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				return 0, err | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			price += cpus | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | 	ram, err := pricing.GetPrice(r.RAMLocated, r.ExplicitBookingDurationS, *r.UsageStart, *r.UsageEnd, "ram") | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return 0, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	price += ram | 
					
						
							|  |  |  | 	return price, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  | * FillWithDefaultProcessingUsage fills the order item with the default processing usage | 
					
						
							|  |  |  | * it depends on the processing usage only if nothing is set, during order | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2025-01-13 11:24:07 +01:00
										 |  |  | func (i *PricedComputeResource) FillWithDefaultProcessingUsage(usage *ProcessingUsage) { | 
					
						
							| 
									
										
										
										
											2024-12-12 16:25:47 +01:00
										 |  |  | 	for _, cpu := range usage.CPUs { | 
					
						
							|  |  |  | 		if _, ok := i.CPUsLocated[cpu.Model]; !ok { | 
					
						
							|  |  |  | 			i.CPUsLocated[cpu.Model] = 0 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if i.CPUsLocated[cpu.Model] < float64(cpu.Cores) { | 
					
						
							|  |  |  | 			i.CPUsLocated[cpu.Model] = float64(cpu.Cores) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, cpu := range usage.GPUs { | 
					
						
							|  |  |  | 		i.GPUsLocated[cpu.Model] = 1 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	i.RAMLocated = usage.RAM.SizeGb | 
					
						
							| 
									
										
										
										
											2024-11-28 16:49:41 +01:00
										 |  |  | } |