Compare commits

..

9 Commits

Author SHA1 Message Date
alu ad6b8211b3 add Auth and InstancePath types 2026-06-08 18:49:31 +00:00
alu 52ac2c2b97 add mapstructure tags to types,
improve function documentation
2026-05-26 20:22:50 +00:00
alu 48fa4c0613 minor fixes 2026-05-26 20:04:58 +00:00
alu 0936e8e5a5 fix VMID Max naming issue,
add mapstructure decode tags
2026-05-22 21:30:01 +00:00
alu be50bf3428 add pool mapping to Instance type 2026-05-22 18:49:01 +00:00
alu cc53d7bdea improve ParseGroupname and ParseUsername using regex 2026-04-27 21:52:40 +00:00
alu 7fc7584984 improve Pool type member naming 2026-04-24 22:21:04 +00:00
alu 858c5889f1 update backup type with per instance and total backup count max 2026-04-24 17:54:13 +00:00
alu eeaf366e28 add access util functions, change internal package name to proxmoxaas_common_lib 2026-04-19 17:30:00 +00:00
3 changed files with 155 additions and 80 deletions
+47 -39
View File
@@ -1,88 +1,96 @@
package paas_common_lib package proxmoxaas_common_lib
// all the cookies for proxmoxaas
type Auth struct {
Username string
Token string
CSRF string
AccessManagerTicket string
}
type Pool struct { type Pool struct {
PoolID string `json:"poolid"` PoolID string `json:"poolid" mapstructure:"poolid"`
Path string `json:"-"` // typically /pool/poolid from proxmox, only used internally Groups []Group `json:"groups" mapstructure:"groups"`
Groups []Group `json:"groups"` Resources map[string]any `json:"resources" mapstructure:"resources"`
Resources map[string]any `json:"resources"` Templates Templates `json:"templates" mapstructure:"templates"`
Templates Templates `json:"templates"` AllowedNodes map[string]bool `json:"nodes-allowed" mapstructure:"nodes-allowed"`
AllowedNodes map[string]bool `json:"nodes-allowed"` AllowedVMIDRange VMID `json:"vmid-allowed" mapstructure:"vmid-allowed"`
VMIDRange VMID `json:"vmid-allowed"` AllowedBackups Backups `json:"backups-allowed" mapstructure:"backups-allowed"`
Backups Backups `json:"backups-allowed"` // measured in numbers
} }
// proxmox typically formats as gid-realm for non pve realms // proxmox typically formats as gid-realm for non pve realms
// proxmox realms are formatted without realm values // proxmox realms are formatted without realm values
// I assume that backends store groups by ID only and only proxmox will append the realm string // I assume that backends store groups by ID only and only proxmox will append the realm string
type Groupname struct { type Groupname struct {
GroupID string `json:"gid"` GroupID string `json:"gid" mapstructure:"gid"`
Realm string `json:"realm"` Realm string `json:"realm" mapstructure:"realm"`
} }
type Group struct { type Group struct {
Groupname Groupname `json:"groupname"` Groupname Groupname `json:"groupname" mapstructure:"groupname"`
Role string `json:"role"` // role in owner pool Role string `json:"role" mapstructure:"role"` // role in owner pool
Users []User `json:"users"` Users []User `json:"users" mapstructure:"users"`
} }
type Username struct { // ie userid@realm type Username struct { // ie userid@realm
UserID string `json:"uid"` UserID string `json:"uid" mapstructure:"uid"`
Realm string `json:"realm"` Realm string `json:"realm" mapstructure:"realm"`
} }
type User struct { type User struct {
Username Username `json:"username"` Username Username `json:"username" mapstructure:"username"`
CN string `json:"cn"` // aka first name CN string `json:"cn" mapstructure:"cn"` // aka first name
SN string `json:"sn"` // aka last name SN string `json:"sn" mapstructure:"sn"` // aka last name
Mail string `json:"mail"` Mail string `json:"mail" mapstructure:"mail"`
Password string `json:"password"` // only used for POST requests Password string `json:"password" mapstructure:"password"` // only used for POST requests
} }
type VMID struct { type VMID struct {
Min int `json:"min"` Min int `json:"min" mapstructure:"min"`
MAx int `json:"max"` Max int `json:"max" mapstructure:"max"`
} }
type Backups struct { type Backups struct {
Max int `json:"max"` MaxPerInstance int `json:"max-per-instance" mapstructure:"max-per-instance"`
MaxTotal int `json:"max-total" mapstructure:"max-total"`
} }
type Templates struct { type Templates struct {
Instances struct { Instances struct {
LXC map[string]ResourceTemplate `json:"lxc"` LXC map[string]ResourceTemplate `json:"lxc" mapstructure:"lxc"`
QEMU map[string]ResourceTemplate `json:"qemu"` QEMU map[string]ResourceTemplate `json:"qemu" mapstructure:"qemu"`
} `json:"instances"` } `json:"instances"`
} }
type SimpleResource struct { type SimpleResource struct {
Limits struct { Limits struct {
Global SimpleLimit `json:"global"` Global SimpleLimit `json:"global" mapstructure:"global"`
Nodes map[string]SimpleLimit `json:"nodes"` Nodes map[string]SimpleLimit `json:"nodes" mapstructure:"nodes"`
} `json:"limits"` } `json:"limits"`
} }
type SimpleLimit struct { type SimpleLimit struct {
Max int `json:"max"` Max int `json:"max" mapstructure:"max"`
} }
type MatchResource struct { type MatchResource struct {
Limits struct { Limits struct {
Global []MatchLimit `json:"global"` Global []MatchLimit `json:"global" mapstructure:""`
Nodes map[string][]MatchLimit `json:"nodes"` Nodes map[string][]MatchLimit `json:"nodes" mapstructure:""`
} `json:"limits"` } `json:"limits"`
} }
type MatchLimit struct { type MatchLimit struct {
Match string `json:"match"` Match string `json:"match" mapstructure:""`
Name string `json:"name"` Name string `json:"name" mapstructure:""`
Max int `json:"max"` Max int `json:"max" mapstructure:""`
} }
type ResourceTemplate struct { type ResourceTemplate struct {
Value string `json:"value"` Value string `json:"value" mapstructure:"value"`
Resource struct { Resource struct {
Enabled bool `json:"enabled"` Enabled bool `json:"enabled" mapstructure:"enabled"`
Name string `json:"name"` Name string `json:"name" mapstructure:"name"`
Amount int `json:"amount"` Amount int `json:"amount" mapstructure:"amount"`
} `json:"resource"` } `json:"resource" mapstructure:"resource"`
} }
+59
View File
@@ -0,0 +1,59 @@
package proxmoxaas_common_lib
import (
"fmt"
"regexp"
)
// Converts input groupname object to string representation.
// Uses the format gid-realm.
func (g Groupname) ToString() string {
return fmt.Sprintf("%s-%s", g.GroupID, g.Realm)
}
// Converts input username object to string representation.
// Uses the format uid@realm.
func (u Username) ToString() string {
return fmt.Sprintf("%s-%s", u.UserID, u.Realm)
}
// Parses input groupname string to gid and realm.
// Assumes the format gid-realm or gid if realm is implicitly pve.
// Returns an error if the groupname format was not correct.
func ParseGroupname(groupname string) (Groupname, error) {
g := Groupname{}
// <groupid>-<realm>
m1 := regexp.MustCompilePOSIX("([[:alnum:]]+)-([[:alnum:]]+)")
// <groupid> (implied pve realm)
m2 := regexp.MustCompilePOSIX("([[:alnum:]]+)")
x1 := m1.FindStringSubmatch(groupname)
x2 := m2.FindStringSubmatch(groupname)
if len(x1) == 3 {
g.GroupID = x1[1]
g.Realm = x1[2]
return g, nil
} else if len(x2) == 2 {
g.GroupID = groupname
g.Realm = "pve"
return g, nil
} else {
return g, fmt.Errorf("groupid did not follow the format <groupid> or <groupid>-<realm>")
}
}
// Parses input username string to uid and realm.
// Assumes the format uid@realm.
// Returns an error if the username format was not correct.
func ParseUsername(username string) (Username, error) {
u := Username{}
m := regexp.MustCompilePOSIX("([[:alnum:]]+)@([[:alnum:]]+)")
x := m.FindStringSubmatch(username)
if len(x) == 3 {
u.UserID = x[1]
u.Realm = x[2]
return u, nil
} else {
return u, fmt.Errorf("userid did not follow the format <userid>@<realm>")
}
}
+49 -41
View File
@@ -1,17 +1,17 @@
package paas_common_lib package proxmoxaas_common_lib
type Cluster struct { type Cluster struct {
Nodes map[string]*Node `json:"nodes"` Nodes map[string]*Node `json:"nodes"`
} }
type Node struct { type Node struct {
Name string `json:"name"` Name string `json:"name" mapstructure:"name"`
Cores uint64 `json:"cores"` Cores uint64 `json:"cores" mapstructure:"cores"`
Memory uint64 `json:"memory"` Memory uint64 `json:"memory" mapstructure:"memory"`
Swap uint64 `json:"swap"` Swap uint64 `json:"swap" mapstructure:"swap"`
Devices map[DeviceBus]*Device `json:"devices"` Devices map[DeviceBus]*Device `json:"devices" mapstructure:"devices"`
Instances map[InstanceID]*Instance `json:"instances"` Instances map[InstanceID]*Instance `json:"instances" mapstructure:"instances"`
Proctypes []string `json:"cpus"` Proctypes []string `json:"cpus" mapstructure:"cpus"`
} }
type InstanceID uint64 type InstanceID uint64
@@ -21,16 +21,24 @@ const VM InstanceType = "VM"
const CT InstanceType = "CT" const CT InstanceType = "CT"
type Instance struct { type Instance struct {
Type InstanceType `json:"type"` Type InstanceType `json:"type" mapstructure:"type"`
Name string `json:"name"` Name string `json:"name" mapstructure:"name"`
Proctype string `json:"cpu"` Proctype string `json:"cpu" mapstructure:"cpu"`
Cores uint64 `json:"cores"` Cores uint64 `json:"cores" mapstructure:"cores"`
Memory uint64 `json:"memory"` Memory uint64 `json:"memory" mapstructure:"memory"`
Swap uint64 `json:"swap"` Swap uint64 `json:"swap" mapstructure:"swap"`
Volumes map[VolumeID]*Volume `json:"volumes"` Volumes map[VolumeID]*Volume `json:"volumes" mapstructure:"volumes"`
Nets map[NetID]*Net `json:"nets"` Nets map[NetID]*Net `json:"nets" mapstructure:"nets"`
Devices map[DeviceID]*Device `json:"devices"` Devices map[DeviceID]*Device `json:"devices" mapstructure:"devices"`
Boot BootOrder `json:"boot"` Boot BootOrder `json:"boot" mapstructure:"boot"`
Pool string `json:"pool" mapstructure:"pool"` // todo: this should be actual pool
}
// parsed vmpath data (ie node/type/id)
type InstancePath struct {
NodeName string
InstanceType InstanceType
InstanceID InstanceID
} }
var VolumeTypes = []string{ var VolumeTypes = []string{
@@ -44,43 +52,43 @@ var VolumeTypes = []string{
type VolumeID string type VolumeID string
type Volume struct { type Volume struct {
Volume_ID VolumeID `json:"volume_id"` Volume_ID VolumeID `json:"volume_id" mapstructure:"volume_id"`
Type string `json:"type"` Type string `json:"type" mapstructure:"type"`
Storage string `json:"storage"` Storage string `json:"storage" mapstructure:"storage"`
Format string `json:"format"` Format string `json:"format" mapstructure:"format"`
Size uint64 `json:"size"` Size uint64 `json:"size" mapstructure:"size"`
File string `json:"file"` File string `json:"file" mapstructure:"file"`
MP string `json:"mp"` MP string `json:"mp" mapstructure:"mp"`
} }
type NetID string type NetID string
type Net struct { type Net struct {
Net_ID NetID `json:"net_id"` Net_ID NetID `json:"net_id" mapstructure:"net_id"`
Value string `json:"value"` Value string `json:"value" mapstructure:"value"`
Rate uint64 `json:"rate"` Rate uint64 `json:"rate" mapstructure:"rate"`
VLAN uint64 `json:"vlan"` VLAN uint64 `json:"vlan" mapstructure:"vlan"`
} }
type DeviceID string type DeviceID string
type DeviceBus string type DeviceBus string
type Device struct { type Device struct {
Device_ID DeviceID `json:"device_id"` Device_ID DeviceID `json:"device_id" mapstructure:"device_id"`
Device_Bus DeviceBus `json:"device_bus"` Device_Bus DeviceBus `json:"device_bus" mapstructure:"device_bus"`
Device_Name string `json:"device_name"` Device_Name string `json:"device_name" mapstructure:"device_name"`
Vendor_Name string `json:"vendor_name"` Vendor_Name string `json:"vendor_name" mapstructure:"vendor_name"`
Functions map[FunctionID]*Function `json:"functions"` Functions map[FunctionID]*Function `json:"functions" mapstructure:"functions"`
Reserved bool `json:"reserved"` Reserved bool `json:"reserved" mapstructure:"reserved"`
} }
type FunctionID string type FunctionID string
type Function struct { type Function struct {
Function_ID FunctionID `json:"function_id"` Function_ID FunctionID `json:"function_id" mapstructure:"function_id"`
Function_Name string `json:"subsystem_device_name"` Function_Name string `json:"subsystem_device_name" mapstructure:"subsystem_device_name"`
Vendor_Name string `json:"subsystem_vendor_name"` Vendor_Name string `json:"subsystem_vendor_name" mapstructure:"subsystem_vendor_name"`
Reserved bool `json:"reserved"` Reserved bool `json:"reserved" mapstructure:"reserved"`
} }
type BootOrder struct { type BootOrder struct {
Enabled []any `json:"enabled"` Enabled []any `json:"enabled" mapstructure:"enabled"`
Disabled []any `json:"disabled"` Disabled []any `json:"disabled" mapstructure:"disabled"`
} }