2024-07-18 11:51:12 +02:00
package resources
2024-07-19 10:54:58 +02:00
import (
2024-12-12 16:25:47 +01:00
"slices"
"cloud.o-forge.io/core/oc-lib/config"
"cloud.o-forge.io/core/oc-lib/models/common/pricing"
"cloud.o-forge.io/core/oc-lib/models/peer"
2024-11-28 11:05:54 +01:00
"cloud.o-forge.io/core/oc-lib/models/resources/resource_model"
"cloud.o-forge.io/core/oc-lib/models/utils"
2024-12-12 16:25:47 +01:00
"cloud.o-forge.io/core/oc-lib/tools"
"github.com/biter777/countries"
2024-07-19 10:54:58 +02:00
)
2024-07-18 11:51:12 +02:00
// AbstractResource is the struct containing all of the attributes commons to all ressources
// Resource is the interface to be implemented by all classes inheriting from Resource to have the same behavior
2024-07-23 11:22:50 +02:00
// http://www.inanzzz.com/index.php/post/wqbs/a-basic-usage-of-int-and-string-enum-types-in-golang
2024-12-12 16:25:47 +01:00
/ *
* AbstractResource is a struct that represents a resource
* it defines the resource data
* /
2025-01-14 09:15:50 +01:00
type AbstractResource struct {
2025-01-13 14:52:41 +01:00
utils . AbstractObject // AbstractObject contains the basic fields of an object (id, name)
Logo string ` json:"logo,omitempty" bson:"logo,omitempty" validate:"required" ` // Logo is the logo of the resource
Description string ` json:"description,omitempty" bson:"description,omitempty" ` // Description is the description of the resource
ShortDescription string ` json:"short_description,omitempty" bson:"short_description,omitempty" validate:"required" ` // ShortDescription is the short description of the resource
Owners [ ] utils . Owner ` json:"owners,omitempty" bson:"owners,omitempty" ` // Owners is the list of owners of the resource
ResourceModel * resource_model . ResourceModel ` json:"resource_model,omitempty" bson:"resource_model,omitempty" ` // ResourceModel is the model of the resource
UsageRestrictions string ` bson:"usage_restrictions,omitempty" json:"usage_restrictions,omitempty" `
2025-01-14 09:15:50 +01:00
SelectedInstanceIndex * int ` json:"selected_instance_index,omitempty" bson:"selected_instance_index,omitempty" ` // SelectedInstance is the selected instance
2025-01-13 14:52:41 +01:00
}
2025-01-14 09:15:50 +01:00
func ( r * AbstractResource ) SetSelection ( selection * int ) {
r . SelectedInstanceIndex = selection
}
func ( r * AbstractResource ) Transform ( ) utils . DBObject {
2025-01-14 08:17:22 +01:00
return r
}
2025-01-14 09:15:50 +01:00
func ( r * AbstractResource ) StoreDraftDefault ( ) {
2024-12-12 16:25:47 +01:00
r . IsDraft = true
}
2025-01-14 09:15:50 +01:00
func ( r * AbstractResource ) CanUpdate ( set utils . DBObject ) ( bool , utils . DBObject ) {
2024-12-12 16:25:47 +01:00
if r . IsDraft != set . IsDrafted ( ) && set . IsDrafted ( ) {
return true , set // only state can be updated
}
return r . IsDraft != set . IsDrafted ( ) && set . IsDrafted ( ) , set
}
2025-01-14 09:15:50 +01:00
func ( r * AbstractResource ) CanDelete ( ) bool {
2024-12-12 16:25:47 +01:00
return r . IsDraft // only draft bookings can be deleted
}
2025-01-14 09:15:50 +01:00
func ( ao * AbstractResource ) GetAccessor ( request * tools . APIRequest ) utils . Accessor {
2024-12-12 16:25:47 +01:00
return nil
}
2025-01-14 09:15:50 +01:00
func ( abs * AbstractResource ) SetResourceModel ( model * resource_model . ResourceModel ) {
2024-12-12 16:25:47 +01:00
abs . ResourceModel = model
}
2025-01-14 09:15:50 +01:00
type AbstractIntanciatedResource [ T ResourceInstanceITF ] struct {
AbstractResource // AbstractResource contains the basic fields of an object (id, name)
Instances [ ] T ` json:"instances,omitempty" bson:"instances,omitempty" ` // Bill is the bill of the resource // Bill is the bill of the resource
}
func ( abs * AbstractIntanciatedResource [ T ] ) ConvertToPricedResource (
2025-01-13 11:24:07 +01:00
t tools . DataType , request * tools . APIRequest ) pricing . PricedItemITF {
instances := map [ string ] string { }
profiles := map [ string ] [ ] pricing . PricingProfileITF { }
2024-12-12 16:25:47 +01:00
for _ , instance := range abs . Instances {
2025-01-13 11:24:07 +01:00
instances [ instance . GetID ( ) ] = instance . GetName ( )
profiles [ instance . GetID ( ) ] = instance . GetPricingsProfiles ( request . PeerID , request . Groups )
}
return & PricedResource {
Name : abs . Name ,
Logo : abs . Logo ,
ResourceID : abs . UUID ,
ResourceType : t ,
InstancesRefs : instances ,
PricingProfiles : profiles ,
CreatorID : abs . CreatorID ,
2024-11-28 11:05:54 +01:00
}
}
2025-01-14 09:15:50 +01:00
func ( abs * AbstractIntanciatedResource [ T ] ) SetAllowedInstances ( request * tools . APIRequest ) {
2025-01-13 11:24:07 +01:00
abs . Instances = verifyAuthAction [ T ] ( abs . Instances , request )
2024-12-16 12:17:20 +01:00
}
2025-01-14 09:15:50 +01:00
func ( d * AbstractIntanciatedResource [ T ] ) Trim ( ) {
2024-12-16 12:17:20 +01:00
if ok , _ := ( & peer . Peer { AbstractObject : utils . AbstractObject { UUID : d . CreatorID } } ) . IsMySelf ( ) ; ! ok {
for _ , instance := range d . Instances {
instance . ClearPeerGroups ( )
}
}
}
2025-01-14 09:15:50 +01:00
func ( abs * AbstractIntanciatedResource [ T ] ) VerifyAuth ( request * tools . APIRequest ) bool {
2024-12-16 12:17:20 +01:00
return len ( verifyAuthAction [ T ] ( abs . Instances , request ) ) > 0 || abs . AbstractObject . VerifyAuth ( request )
}
2025-01-13 11:24:07 +01:00
func verifyAuthAction [ T ResourceInstanceITF ] ( baseInstance [ ] T , request * tools . APIRequest ) [ ] T {
2024-12-12 16:25:47 +01:00
instances := [ ] T { }
for _ , instance := range baseInstance {
_ , peerGroups := instance . GetPeerGroups ( )
for _ , peers := range peerGroups {
if request == nil {
continue
}
if grps , ok := peers [ request . PeerID ] ; ok || config . GetConfig ( ) . Whitelist {
if ( ok && slices . Contains ( grps , "*" ) ) || ( ! ok && config . GetConfig ( ) . Whitelist ) {
instances = append ( instances , instance )
}
for _ , grp := range grps {
if slices . Contains ( request . Groups , grp ) {
instances = append ( instances , instance )
}
}
}
}
}
return instances
}
2025-01-14 08:42:12 +01:00
type GeoPoint struct {
Latitude float64 ` json:"latitude,omitempty" bson:"latitude,omitempty" `
Longitude float64 ` json:"longitude,omitempty" bson:"longitude,omitempty" `
}
2024-12-12 16:25:47 +01:00
type ResourceInstance [ T ResourcePartnerITF ] struct {
2025-01-14 08:42:12 +01:00
UUID string ` json:"id,omitempty" bson:"id,omitempty" `
Name string ` json:"name,omitempty" bson:"name,omitempty" `
Location GeoPoint ` json:"location,omitempty" bson:"location,omitempty" `
Country countries . CountryCode ` json:"country,omitempty" bson:"country,omitempty" `
AccessProtocol string ` json:"access_protocol,omitempty" bson:"access_protocol,omitempty" `
2025-01-14 09:15:50 +01:00
Partnerships [ ] T ` json:"partnerships,omitempty" bson:"partnerships,omitempty" `
2024-12-12 16:25:47 +01:00
}
func ( ri * ResourceInstance [ T ] ) GetID ( ) string {
return ri . UUID
}
2025-01-13 11:24:07 +01:00
func ( ri * ResourceInstance [ T ] ) GetName ( ) string {
return ri . Name
}
func ( ri * ResourceInstance [ T ] ) GetPricingsProfiles ( peerID string , groups [ ] string ) [ ] pricing . PricingProfileITF {
pricings := [ ] pricing . PricingProfileITF { }
for _ , p := range ri . Partnerships {
pricings = append ( pricings , p . GetPricingsProfiles ( peerID , groups ) ... )
2024-12-12 16:25:47 +01:00
}
2025-01-13 11:24:07 +01:00
return pricings
2024-12-12 16:25:47 +01:00
}
func ( ri * ResourceInstance [ T ] ) GetPeerGroups ( ) ( [ ] ResourcePartnerITF , [ ] map [ string ] [ ] string ) {
groups := [ ] map [ string ] [ ] string { }
partners := [ ] ResourcePartnerITF { }
for _ , p := range ri . Partnerships {
partners = append ( partners , p )
groups = append ( groups , p . GetPeerGroups ( ) )
}
return partners , groups
}
func ( ri * ResourceInstance [ T ] ) ClearPeerGroups ( ) {
for _ , p := range ri . Partnerships {
p . ClearPeerGroups ( )
}
}
type ResourcePartnerShip [ T pricing . PricingProfileITF ] struct {
Namespace string ` json:"namespace" bson:"namespace" default:"default-namespace" `
PeerGroups map [ string ] [ ] string ` json:"peer_groups,omitempty" bson:"peer_groups,omitempty" `
PricingProfiles map [ string ] T ` json:"pricing,omitempty" bson:"pricing,omitempty" `
}
2025-01-13 11:24:07 +01:00
func ( ri * ResourcePartnerShip [ T ] ) GetPricingsProfiles ( peerID string , groups [ ] string ) [ ] pricing . PricingProfileITF {
if ri . PeerGroups [ peerID ] != nil {
for _ , p := range ri . PeerGroups [ peerID ] {
if slices . Contains ( groups , p ) {
profiles := [ ] pricing . PricingProfileITF { }
for _ , ri := range ri . PricingProfiles {
profiles = append ( profiles , ri )
}
return profiles
}
}
}
return [ ] pricing . PricingProfileITF { }
2024-12-12 16:25:47 +01:00
}
func ( rp * ResourcePartnerShip [ T ] ) GetPeerGroups ( ) map [ string ] [ ] string {
return rp . PeerGroups
}
func ( rp * ResourcePartnerShip [ T ] ) ClearPeerGroups ( ) {
rp . PeerGroups = map [ string ] [ ] string { }
}