Live x Resource Synergy
This commit is contained in:
@@ -1,18 +1,13 @@
|
|||||||
package live
|
package live
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type LiveInterface interface {
|
type LiveInterface interface {
|
||||||
utils.DBObject
|
utils.DBObject
|
||||||
|
IsCompatible(service map[string]interface{}) bool
|
||||||
GetMonitorPath() string
|
GetMonitorPath() string
|
||||||
GetResourcesID() []string
|
GetResourcesID() []string
|
||||||
SetResourcesID(string)
|
SetResourcesID(string)
|
||||||
GetResourceAccessor(request *tools.APIRequest) utils.Accessor
|
|
||||||
GetResource() resources.ResourceInterface
|
|
||||||
GetResourceInstance() resources.ResourceInstanceITF
|
|
||||||
SetResourceInstance(res resources.ResourceInterface, i resources.ResourceInstanceITF) resources.ResourceInterface
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package live
|
|||||||
import (
|
import (
|
||||||
"slices"
|
"slices"
|
||||||
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
"github.com/biter777/countries"
|
"github.com/biter777/countries"
|
||||||
@@ -32,13 +31,17 @@ type LiveCerts struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO in the future multiple type of certs depending of infra type
|
// TODO in the future multiple type of certs depending of infra type
|
||||||
|
type GeoPoint struct {
|
||||||
|
Latitude float64 `json:"latitude,omitempty" bson:"latitude,omitempty"`
|
||||||
|
Longitude float64 `json:"longitude,omitempty" bson:"longitude,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type AbstractLive struct {
|
type AbstractLive struct {
|
||||||
utils.AbstractObject
|
utils.AbstractObject
|
||||||
Certs LiveCerts `json:"certs,omitempty" bson:"certs,omitempty"`
|
Certs LiveCerts `json:"certs,omitempty" bson:"certs,omitempty"`
|
||||||
|
|
||||||
MonitorPath string `json:"monitor_path,omitempty" bson:"monitor_path,omitempty"`
|
MonitorPath string `json:"monitor_path,omitempty" bson:"monitor_path,omitempty"`
|
||||||
Location resources.GeoPoint `json:"location,omitempty" bson:"location,omitempty"`
|
Location GeoPoint `json:"location,omitempty" bson:"location,omitempty"`
|
||||||
Country countries.CountryCode `json:"country,omitempty" bson:"country,omitempty"`
|
Country countries.CountryCode `json:"country,omitempty" bson:"country,omitempty"`
|
||||||
AccessProtocol string `json:"access_protocol,omitempty" bson:"access_protocol,omitempty"`
|
AccessProtocol string `json:"access_protocol,omitempty" bson:"access_protocol,omitempty"`
|
||||||
ResourcesID []string `json:"resources_id" bson:"resources_id"`
|
ResourcesID []string `json:"resources_id" bson:"resources_id"`
|
||||||
@@ -71,9 +74,9 @@ func (d *AbstractLive) GetResourcesID() []string {
|
|||||||
return d.ResourcesID
|
return d.ResourcesID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *AbstractLive) SetResourcesID(id string) {
|
func (d *AbstractLive) SetResourcesID(resourcesid string) {
|
||||||
if !slices.Contains(d.ResourcesID, id) {
|
if slices.Contains(d.ResourcesID, resourcesid) {
|
||||||
d.ResourcesID = append(d.ResourcesID, id)
|
d.ResourcesID = append(d.ResourcesID, resourcesid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package live
|
|||||||
import (
|
import (
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
)
|
)
|
||||||
@@ -12,6 +11,13 @@ import (
|
|||||||
* LiveDatacenter is a struct that represents a compute units in your datacenters
|
* LiveDatacenter is a struct that represents a compute units in your datacenters
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
type ComputeNode struct {
|
||||||
|
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
||||||
|
Quantity int64 `json:"quantity" bson:"quantity" default:"1"`
|
||||||
|
RAM *models.RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
|
||||||
|
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
|
||||||
|
}
|
||||||
type LiveDatacenter struct {
|
type LiveDatacenter struct {
|
||||||
AbstractLive
|
AbstractLive
|
||||||
|
|
||||||
@@ -26,25 +32,13 @@ type LiveDatacenter struct {
|
|||||||
AnnualCO2Emissions float64 `json:"annual_co2_emissions,omitempty" bson:"co2_emissions,omitempty"`
|
AnnualCO2Emissions float64 `json:"annual_co2_emissions,omitempty" bson:"co2_emissions,omitempty"`
|
||||||
CPUs map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"` // CPUs is the list of CPUs key is model
|
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
|
GPUs map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"` // GPUs is the list of GPUs key is model
|
||||||
Nodes []*resources.ComputeNode `json:"nodes,omitempty" bson:"nodes,omitempty"`
|
Nodes []*ComputeNode `json:"nodes,omitempty" bson:"nodes,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *LiveDatacenter) IsCompatible(service map[string]interface{}) bool {
|
||||||
|
return service["infrastructure"] == r.Infrastructure && service["architecture"] == r.Architecture
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LiveDatacenter) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
func (d *LiveDatacenter) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
||||||
return NewAccessor[*LiveDatacenter](tools.LIVE_DATACENTER, request) // Create a new instance of the accessor
|
return NewAccessor[*LiveDatacenter](tools.LIVE_DATACENTER, request) // Create a new instance of the accessor
|
||||||
}
|
}
|
||||||
func (d *LiveDatacenter) GetResourceAccessor(request *tools.APIRequest) utils.Accessor {
|
|
||||||
return resources.NewAccessor[*resources.ComputeResource](tools.COMPUTE_RESOURCE, request)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveDatacenter) GetResource() resources.ResourceInterface {
|
|
||||||
return &resources.ComputeResource{}
|
|
||||||
}
|
|
||||||
func (d *LiveDatacenter) GetResourceInstance() resources.ResourceInstanceITF {
|
|
||||||
return &resources.ComputeResourceInstance{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveDatacenter) SetResourceInstance(res resources.ResourceInterface, i resources.ResourceInstanceITF) resources.ResourceInterface {
|
|
||||||
r := res.(*resources.ComputeResource)
|
|
||||||
r.Instances = append(r.Instances, i.(*resources.ComputeResourceInstance))
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package live
|
package live
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
|
|
||||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||||
"cloud.o-forge.io/core/oc-lib/logs"
|
"cloud.o-forge.io/core/oc-lib/logs"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
@@ -32,67 +29,11 @@ func NewAccessor[T LiveInterface](t tools.DataType, request *tools.APIRequest) *
|
|||||||
}
|
}
|
||||||
return &LiveDatacenter{}
|
return &LiveDatacenter{}
|
||||||
},
|
},
|
||||||
|
NotImplemented: []string{"CopyOne"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Nothing special here, just the basic CRUD operations
|
|
||||||
*/
|
|
||||||
func (a *liveMongoAccessor[T]) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
|
|
||||||
// is a publisher... that become a resources.
|
|
||||||
if data.IsDrafted() {
|
|
||||||
return nil, 422, errors.New("can't publish a drafted compute units")
|
|
||||||
}
|
|
||||||
live := data.(T)
|
|
||||||
/*if live.GetMonitorPath() == "" || live.GetID() != "" {
|
|
||||||
return nil, 422, errors.New("publishing is only allowed is it can be monitored and be accessible")
|
|
||||||
}*/
|
|
||||||
if res, code, err := a.LoadOne(live.GetID()); err != nil {
|
|
||||||
return nil, code, err
|
|
||||||
} else {
|
|
||||||
live = res.(T)
|
|
||||||
}
|
|
||||||
resAccess := live.GetResourceAccessor(a.Request)
|
|
||||||
instance := live.GetResourceInstance()
|
|
||||||
b, _ := json.Marshal(live)
|
|
||||||
json.Unmarshal(b, instance)
|
|
||||||
|
|
||||||
if len(live.GetResourcesID()) > 0 {
|
|
||||||
for _, r := range live.GetResourcesID() {
|
|
||||||
res, code, err := resAccess.LoadOne(r)
|
|
||||||
if err == nil {
|
|
||||||
return nil, code, err
|
|
||||||
}
|
|
||||||
existingResource := live.GetResource()
|
|
||||||
b, _ := json.Marshal(res)
|
|
||||||
json.Unmarshal(b, existingResource)
|
|
||||||
live.SetResourceInstance(existingResource, instance)
|
|
||||||
resAccess.UpdateOne(existingResource.Serialize(existingResource), existingResource.GetID())
|
|
||||||
}
|
|
||||||
if live.GetID() != "" {
|
|
||||||
return a.LoadOne(live.GetID())
|
|
||||||
} else {
|
|
||||||
return a.StoreOne(live)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r := live.GetResource()
|
|
||||||
b, _ := json.Marshal(live)
|
|
||||||
json.Unmarshal(b, &r)
|
|
||||||
live.SetResourceInstance(r, instance)
|
|
||||||
res, code, err := utils.GenericStoreOne(r, resAccess)
|
|
||||||
if err != nil {
|
|
||||||
return nil, code, err
|
|
||||||
}
|
|
||||||
live.SetResourcesID(res.GetID())
|
|
||||||
if live.GetID() != "" {
|
|
||||||
return a.UpdateOne(live.Serialize(live), live.GetID())
|
|
||||||
} else {
|
|
||||||
return a.StoreOne(live)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wfa *liveMongoAccessor[T]) LoadAll(isDraft bool, offset int64, limit int64) ([]utils.ShallowDBObject, int, error) {
|
func (wfa *liveMongoAccessor[T]) LoadAll(isDraft bool, offset int64, limit int64) ([]utils.ShallowDBObject, int, error) {
|
||||||
return utils.GenericLoadAll[T](wfa.GetExec(isDraft), isDraft, wfa, offset, limit)
|
return utils.GenericLoadAll[T](wfa.GetExec(isDraft), isDraft, wfa, offset, limit)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,24 @@
|
|||||||
package live
|
package live
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ServiceProtocol int
|
||||||
|
|
||||||
|
const (
|
||||||
|
HTTP ServiceProtocol = iota
|
||||||
|
GRPC
|
||||||
|
WEBSOCKET
|
||||||
|
TCP
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p ServiceProtocol) String() string {
|
||||||
|
return [...]string{"HTTP", "GRPC", "WEBSOCKET", "TCP"}[p]
|
||||||
|
}
|
||||||
|
|
||||||
// LiveService is the authoritative description of a hosted service run by the peer.
|
// LiveService is the authoritative description of a hosted service run by the peer.
|
||||||
// MaxConcurrent is the only capacity dimension that matters for scheduling:
|
// MaxConcurrent is the only capacity dimension that matters for scheduling:
|
||||||
// it caps the number of simultaneous callers the service can accept.
|
// it caps the number of simultaneous callers the service can accept.
|
||||||
@@ -14,29 +27,16 @@ import (
|
|||||||
type LiveService struct {
|
type LiveService struct {
|
||||||
AbstractLive
|
AbstractLive
|
||||||
MaxConcurrent int `json:"max_concurrent" bson:"max_concurrent"`
|
MaxConcurrent int `json:"max_concurrent" bson:"max_concurrent"`
|
||||||
Protocol resources.ServiceProtocol `json:"protocol" bson:"protocol" default:"0"`
|
Protocol ServiceProtocol `json:"protocol" bson:"protocol" default:"0"`
|
||||||
EndpointPattern string `json:"endpoint_pattern,omitempty" bson:"endpoint_pattern,omitempty"`
|
EndpointPattern string `json:"endpoint_pattern,omitempty" bson:"endpoint_pattern,omitempty"`
|
||||||
HealthCheckPath string `json:"health_check_path,omitempty" bson:"health_check_path,omitempty"`
|
HealthCheckPath string `json:"health_check_path,omitempty" bson:"health_check_path,omitempty"`
|
||||||
|
Infrastructure enum.InfrastructureType `json:"infrastructure" bson:"infrastructure" default:"-1"` // Infrastructure is the infrastructure
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LiveService) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
func (d *LiveService) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
||||||
return NewAccessor[*LiveService](tools.LIVE_SERVICE, request)
|
return NewAccessor[*LiveService](tools.LIVE_SERVICE, request)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LiveService) GetResourceAccessor(request *tools.APIRequest) utils.Accessor {
|
func (r *LiveService) IsCompatible(service map[string]interface{}) bool {
|
||||||
return resources.NewAccessor[*resources.ServiceResource](tools.SERVICE_RESOURCE, request)
|
return service["infrastructure"] == r.Infrastructure
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveService) GetResource() resources.ResourceInterface {
|
|
||||||
return &resources.ServiceResource{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveService) GetResourceInstance() resources.ResourceInstanceITF {
|
|
||||||
return &resources.ServiceInstance{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveService) SetResourceInstance(res resources.ResourceInterface, i resources.ResourceInstanceITF) resources.ResourceInterface {
|
|
||||||
r := res.(*resources.ServiceResource)
|
|
||||||
r.AddInstances(i)
|
|
||||||
return r
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package live
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources"
|
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
)
|
)
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
type LiveStorage struct {
|
type LiveStorage struct {
|
||||||
AbstractLive
|
AbstractLive
|
||||||
|
|
||||||
|
StorageType enum.StorageType `bson:"storage_type" json:"storage_type" default:"-1"`
|
||||||
Source string `bson:"source,omitempty" json:"source,omitempty"` // Source is the source of the storage
|
Source string `bson:"source,omitempty" json:"source,omitempty"` // Source is the source of the storage
|
||||||
Path string `bson:"path,omitempty" json:"path,omitempty"` // Path is the store folders in the source
|
Path string `bson:"path,omitempty" json:"path,omitempty"` // Path is the store folders in the source
|
||||||
Local bool `bson:"local" json:"local"`
|
Local bool `bson:"local" json:"local"`
|
||||||
@@ -25,22 +25,10 @@ type LiveStorage struct {
|
|||||||
Throughput string `bson:"throughput,omitempty" json:"throughput,omitempty"` // Throughput is the throughput of the storage
|
Throughput string `bson:"throughput,omitempty" json:"throughput,omitempty"` // Throughput is the throughput of the storage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *LiveStorage) IsCompatible(service map[string]interface{}) bool {
|
||||||
|
return service["storage_type"] == r.StorageType
|
||||||
|
}
|
||||||
|
|
||||||
func (d *LiveStorage) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
func (d *LiveStorage) GetAccessor(request *tools.APIRequest) utils.Accessor {
|
||||||
return NewAccessor[*LiveStorage](tools.LIVE_STORAGE, request) // Create a new instance of the accessor
|
return NewAccessor[*LiveStorage](tools.LIVE_STORAGE, request) // Create a new instance of the accessor
|
||||||
}
|
}
|
||||||
func (d *LiveStorage) GetResourceAccessor(request *tools.APIRequest) utils.Accessor {
|
|
||||||
return resources.NewAccessor[*resources.StorageResource](tools.STORAGE_RESOURCE, request)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveStorage) GetResource() resources.ResourceInterface {
|
|
||||||
return &resources.StorageResource{}
|
|
||||||
}
|
|
||||||
func (d *LiveStorage) GetResourceInstance() resources.ResourceInstanceITF {
|
|
||||||
return &resources.StorageResourceInstance{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LiveStorage) SetResourceInstance(res resources.ResourceInterface, i resources.ResourceInstanceITF) resources.ResourceInterface {
|
|
||||||
r := res.(*resources.StorageResource)
|
|
||||||
r.Instances = append(r.Instances, i.(*resources.StorageResourceInstance))
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -79,18 +79,6 @@ func TestLiveDatacenter_GetAccessor_NilRequest(t *testing.T) {
|
|||||||
assert.NotNil(t, acc)
|
assert.NotNil(t, acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLiveDatacenter_GetResource(t *testing.T) {
|
|
||||||
dc := &live.LiveDatacenter{}
|
|
||||||
res := dc.GetResource()
|
|
||||||
assert.NotNil(t, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLiveDatacenter_GetResourceInstance(t *testing.T) {
|
|
||||||
dc := &live.LiveDatacenter{}
|
|
||||||
inst := dc.GetResourceInstance()
|
|
||||||
assert.NotNil(t, inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLiveDatacenter_IDAndName(t *testing.T) {
|
func TestLiveDatacenter_IDAndName(t *testing.T) {
|
||||||
dc := &live.LiveDatacenter{}
|
dc := &live.LiveDatacenter{}
|
||||||
dc.AbstractLive.AbstractObject = utils.AbstractObject{UUID: "dc-id", Name: "dc-name"}
|
dc.AbstractLive.AbstractObject = utils.AbstractObject{UUID: "dc-id", Name: "dc-name"}
|
||||||
@@ -124,18 +112,6 @@ func TestLiveStorage_GetAccessor(t *testing.T) {
|
|||||||
assert.NotNil(t, acc)
|
assert.NotNil(t, acc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLiveStorage_GetResource(t *testing.T) {
|
|
||||||
s := &live.LiveStorage{}
|
|
||||||
res := s.GetResource()
|
|
||||||
assert.NotNil(t, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLiveStorage_GetResourceInstance(t *testing.T) {
|
|
||||||
s := &live.LiveStorage{}
|
|
||||||
inst := s.GetResourceInstance()
|
|
||||||
assert.NotNil(t, inst)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLiveStorage_SetResourcesID_NoDuplication(t *testing.T) {
|
func TestLiveStorage_SetResourcesID_NoDuplication(t *testing.T) {
|
||||||
s := &live.LiveStorage{}
|
s := &live.LiveStorage{}
|
||||||
s.SetResourcesID("storage-1")
|
s.SetResourcesID("storage-1")
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/live"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -46,14 +47,6 @@ func (abs *ComputeResource) ConvertToPricedResource(t tools.DataType, selectedIn
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ComputeNode struct {
|
|
||||||
Name string `json:"name,omitempty" bson:"name,omitempty"`
|
|
||||||
Quantity int64 `json:"quantity" bson:"quantity" default:"1"`
|
|
||||||
RAM *models.RAM `bson:"ram,omitempty" json:"ram,omitempty"` // RAM is the RAM
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
type ComputeResourceInstance struct {
|
type ComputeResourceInstance struct {
|
||||||
ResourceInstance[*ComputeResourcePartnership]
|
ResourceInstance[*ComputeResourcePartnership]
|
||||||
Source string `json:"source,omitempty" bson:"source,omitempty"`
|
Source string `json:"source,omitempty" bson:"source,omitempty"`
|
||||||
@@ -62,7 +55,7 @@ type ComputeResourceInstance struct {
|
|||||||
AnnualCO2Emissions float64 `json:"annual_co2_emissions,omitempty" bson:"co2_emissions,omitempty"`
|
AnnualCO2Emissions float64 `json:"annual_co2_emissions,omitempty" bson:"co2_emissions,omitempty"`
|
||||||
CPUs map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"`
|
CPUs map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"`
|
||||||
GPUs map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"`
|
GPUs map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"`
|
||||||
Nodes []*ComputeNode `json:"nodes,omitempty" bson:"nodes,omitempty"`
|
Nodes []*live.ComputeNode `json:"nodes,omitempty" bson:"nodes,omitempty"`
|
||||||
// AvailableStorages lists storage capabilities activatable on this compute unit (e.g. Minio, local volumes).
|
// AvailableStorages lists storage capabilities activatable on this compute unit (e.g. Minio, local volumes).
|
||||||
// These are shallow StorageResource entries — not independent catalog items — but carry full pricing structure.
|
// These are shallow StorageResource entries — not independent catalog items — but carry full pricing structure.
|
||||||
AvailableStorages []*StorageResource `json:"available_storages,omitempty" bson:"available_storages,omitempty"`
|
AvailableStorages []*StorageResource `json:"available_storages,omitempty" bson:"available_storages,omitempty"`
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"cloud.o-forge.io/core/oc-lib/models/booking"
|
"cloud.o-forge.io/core/oc-lib/models/booking"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/live"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/peer"
|
"cloud.o-forge.io/core/oc-lib/models/peer"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
|
"cloud.o-forge.io/core/oc-lib/models/resources/purchase_resource"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
@@ -250,17 +251,12 @@ func VerifyAuthAction[T ResourceInstanceITF](baseInstance []T, request *tools.AP
|
|||||||
return instances
|
return instances
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeoPoint struct {
|
|
||||||
Latitude float64 `json:"latitude,omitempty" bson:"latitude,omitempty"`
|
|
||||||
Longitude float64 `json:"longitude,omitempty" bson:"longitude,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type ResourceInstance[T ResourcePartnerITF] struct {
|
type ResourceInstance[T ResourcePartnerITF] struct {
|
||||||
utils.AbstractObject
|
utils.AbstractObject
|
||||||
ContentType string `json:"content_type,omitempty" bson:"content_type,omitempty"`
|
ContentType string `json:"content_type,omitempty" bson:"content_type,omitempty"`
|
||||||
LastUpdate time.Time `json:"last_update,omitempty" bson:"last_update,omitempty"`
|
LastUpdate time.Time `json:"last_update,omitempty" bson:"last_update,omitempty"`
|
||||||
Origin OriginMeta `json:"origin,omitempty" bson:"origin,omitempty"`
|
Origin OriginMeta `json:"origin,omitempty" bson:"origin,omitempty"`
|
||||||
Location GeoPoint `json:"location,omitempty" bson:"location,omitempty"`
|
Location live.GeoPoint `json:"location,omitempty" bson:"location,omitempty"`
|
||||||
Country countries.CountryCode `json:"country,omitempty" bson:"country,omitempty"`
|
Country countries.CountryCode `json:"country,omitempty" bson:"country,omitempty"`
|
||||||
AccessProtocol string `json:"access_protocol,omitempty" bson:"access_protocol,omitempty"`
|
AccessProtocol string `json:"access_protocol,omitempty" bson:"access_protocol,omitempty"`
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||||
"cloud.o-forge.io/core/oc-lib/logs"
|
"cloud.o-forge.io/core/oc-lib/logs"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/live"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
)
|
)
|
||||||
@@ -68,7 +69,12 @@ func (dca *ResourceMongoAccessor[T]) LoadOne(id string) (utils.DBObject, int, er
|
|||||||
|
|
||||||
func (dca *ResourceMongoAccessor[T]) UpdateOne(set map[string]interface{}, id string) (utils.DBObject, int, error) {
|
func (dca *ResourceMongoAccessor[T]) UpdateOne(set map[string]interface{}, id string) (utils.DBObject, int, error) {
|
||||||
if dca.GetType() == tools.COMPUTE_RESOURCE {
|
if dca.GetType() == tools.COMPUTE_RESOURCE {
|
||||||
return nil, 404, errors.New("can't update a non existing computing units resource not reported onto compute units catalog")
|
delete(set, "architecture")
|
||||||
|
delete(set, "infrastructure")
|
||||||
|
} else if dca.GetType() == tools.SERVICE_RESOURCE {
|
||||||
|
delete(set, "infrastructure")
|
||||||
|
} else if dca.GetType() == tools.STORAGE_RESOURCE {
|
||||||
|
delete(set, "storage_type")
|
||||||
}
|
}
|
||||||
return utils.GenericUpdateOne(set, id, dca)
|
return utils.GenericUpdateOne(set, id, dca)
|
||||||
}
|
}
|
||||||
@@ -78,16 +84,66 @@ func (dca *ResourceMongoAccessor[T]) ShouldVerifyAuth() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (dca *ResourceMongoAccessor[T]) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
|
func (dca *ResourceMongoAccessor[T]) StoreOne(data utils.DBObject) (utils.DBObject, int, error) {
|
||||||
|
var i string
|
||||||
|
idsToUpdate := []string{}
|
||||||
|
var a utils.Accessor
|
||||||
if dca.GetType() == tools.COMPUTE_RESOURCE {
|
if dca.GetType() == tools.COMPUTE_RESOURCE {
|
||||||
|
r := data.(*ComputeResource)
|
||||||
|
if len(r.Instances) == 0 {
|
||||||
|
return nil, 404, errors.New("can't create a non existing computing units resource with no instances")
|
||||||
|
}
|
||||||
|
a = live.NewAccessor[*live.LiveDatacenter](tools.LIVE_DATACENTER, &tools.APIRequest{Admin: true})
|
||||||
|
res, _, _ := a.LoadOne(r.Instances[0].GetID())
|
||||||
|
if res == nil {
|
||||||
return nil, 404, errors.New("can't create a non existing computing units resource not reported onto compute units catalog")
|
return nil, 404, errors.New("can't create a non existing computing units resource not reported onto compute units catalog")
|
||||||
}
|
}
|
||||||
return utils.GenericStoreOne(data, dca)
|
if !res.(*live.LiveDatacenter).IsCompatible(data.Serialize(data)) {
|
||||||
|
return nil, 404, errors.New("live computing units target is not compatible")
|
||||||
|
}
|
||||||
|
i = res.GetID()
|
||||||
|
idsToUpdate = res.(*live.LiveDatacenter).ResourcesID
|
||||||
|
} else if dca.GetType() == tools.SERVICE_RESOURCE {
|
||||||
|
r := data.(*ServiceResource)
|
||||||
|
if len(r.Instances) == 0 {
|
||||||
|
return nil, 404, errors.New("can't create a non existing service resource with no instances")
|
||||||
|
}
|
||||||
|
a = live.NewAccessor[*live.LiveService](tools.LIVE_SERVICE, &tools.APIRequest{Admin: true})
|
||||||
|
res, _, _ := a.LoadOne(r.Instances[0].GetID())
|
||||||
|
if res == nil {
|
||||||
|
return nil, 404, errors.New("can't create a non existing service resource not reported onto compute units catalog")
|
||||||
|
}
|
||||||
|
if !res.(*live.LiveService).IsCompatible(data.Serialize(data)) {
|
||||||
|
return nil, 404, errors.New("live service target is not compatible")
|
||||||
|
}
|
||||||
|
i = res.GetID()
|
||||||
|
idsToUpdate = res.(*live.LiveService).ResourcesID
|
||||||
|
} else if dca.GetType() == tools.STORAGE_RESOURCE {
|
||||||
|
r := data.(*StorageResource)
|
||||||
|
if len(r.Instances) == 0 {
|
||||||
|
return nil, 404, errors.New("can't create a non existing storage resource with no instances")
|
||||||
|
}
|
||||||
|
a = live.NewAccessor[*live.LiveStorage](tools.LIVE_STORAGE, &tools.APIRequest{Admin: true})
|
||||||
|
res, _, _ := a.LoadOne(r.Instances[0].GetID())
|
||||||
|
if res == nil {
|
||||||
|
return nil, 404, errors.New("can't create a non existing storage resource not reported onto compute units catalog")
|
||||||
|
}
|
||||||
|
if !res.(*live.LiveStorage).IsCompatible(data.Serialize(data)) {
|
||||||
|
return nil, 404, errors.New("live storage target is not compatible")
|
||||||
|
}
|
||||||
|
i = res.GetID()
|
||||||
|
idsToUpdate = res.(*live.LiveStorage).ResourcesID
|
||||||
|
}
|
||||||
|
res, code, err := utils.GenericStoreOne(data, dca)
|
||||||
|
if res != nil && i != "" {
|
||||||
|
idsToUpdate = append(idsToUpdate, res.GetID())
|
||||||
|
a.UpdateOne(map[string]interface{}{
|
||||||
|
"resources_id": idsToUpdate,
|
||||||
|
}, i)
|
||||||
|
}
|
||||||
|
return res, code, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dca *ResourceMongoAccessor[T]) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
|
func (dca *ResourceMongoAccessor[T]) CopyOne(data utils.DBObject) (utils.DBObject, int, error) {
|
||||||
if dca.GetType() == tools.COMPUTE_RESOURCE {
|
|
||||||
return nil, 404, errors.New("can't copy/publish a non existing computing units resource not reported onto compute units catalog")
|
|
||||||
}
|
|
||||||
return dca.StoreOne(data)
|
return dca.StoreOne(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
"cloud.o-forge.io/core/oc-lib/models/common/enum"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
"cloud.o-forge.io/core/oc-lib/models/common/models"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
|
||||||
|
"cloud.o-forge.io/core/oc-lib/models/live"
|
||||||
"cloud.o-forge.io/core/oc-lib/models/utils"
|
"cloud.o-forge.io/core/oc-lib/models/utils"
|
||||||
"cloud.o-forge.io/core/oc-lib/tools"
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
@@ -23,19 +24,6 @@ func (m ServiceMode) String() string {
|
|||||||
return [...]string{"DEPLOYMENT", "HOSTED"}[m]
|
return [...]string{"DEPLOYMENT", "HOSTED"}[m]
|
||||||
}
|
}
|
||||||
|
|
||||||
type ServiceProtocol int
|
|
||||||
|
|
||||||
const (
|
|
||||||
HTTP ServiceProtocol = iota
|
|
||||||
GRPC
|
|
||||||
WEBSOCKET
|
|
||||||
TCP
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p ServiceProtocol) String() string {
|
|
||||||
return [...]string{"HTTP", "GRPC", "WEBSOCKET", "TCP"}[p]
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServiceUsage struct {
|
type ServiceUsage struct {
|
||||||
CPUs map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"`
|
CPUs map[string]*models.CPU `bson:"cpus,omitempty" json:"cpus,omitempty"`
|
||||||
GPUs map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"`
|
GPUs map[string]*models.GPU `bson:"gpus,omitempty" json:"gpus,omitempty"`
|
||||||
@@ -49,7 +37,7 @@ type ServiceUsage struct {
|
|||||||
// Populated for HOSTED instances (endpoint already known) and as a template for DEPLOYMENT.
|
// Populated for HOSTED instances (endpoint already known) and as a template for DEPLOYMENT.
|
||||||
type ServiceResourceAccess struct {
|
type ServiceResourceAccess struct {
|
||||||
Container *models.Container `json:"container,omitempty" bson:"container,omitempty"`
|
Container *models.Container `json:"container,omitempty" bson:"container,omitempty"`
|
||||||
Protocol ServiceProtocol `json:"protocol" bson:"protocol" default:"0"`
|
Protocol live.ServiceProtocol `json:"protocol" bson:"protocol" default:"0"`
|
||||||
EndpointPattern string `json:"endpoint_pattern,omitempty" bson:"endpoint_pattern,omitempty"`
|
EndpointPattern string `json:"endpoint_pattern,omitempty" bson:"endpoint_pattern,omitempty"`
|
||||||
HealthCheckPath string `json:"health_check_path,omitempty" bson:"health_check_path,omitempty"`
|
HealthCheckPath string `json:"health_check_path,omitempty" bson:"health_check_path,omitempty"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user