diff --git a/.stats.yml b/.stats.yml
index 23c324b..32935aa 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
configured_endpoints: 19
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nirvana-labs%2Fnirvana-78dacb6faebeaf3e5cbd36aae89474fb1ba31185f6042fa4790d387c12ba43fa.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nirvana-labs%2Fnirvana-bdc8de991fbbaabca059dd096a38a4fa1cb038f5c78025c47d826eb3c748afa1.yml
diff --git a/README.md b/README.md
index af95a3a..6fe9d72 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,9 @@ func main() {
option.WithAuthToken("My Auth Token"), // defaults to os.LookupEnv("NIRVANA_LABS_AUTH_TOKEN")
)
operation, err := client.VMs.New(context.TODO(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -62,18 +65,12 @@ func main() {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err != nil {
panic(err.Error())
@@ -197,6 +194,9 @@ To handle errors, we recommend that you use the `errors.As` pattern:
```go
_, err := client.VMs.New(context.TODO(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -206,18 +206,12 @@ _, err := client.VMs.New(context.TODO(), vms.VMNewParams{
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err != nil {
var apierr *nirvana.Error
@@ -246,6 +240,9 @@ defer cancel()
client.VMs.New(
ctx,
vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -255,18 +252,12 @@ client.VMs.New(
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
},
// This sets the per-retry timeout
option.WithRequestTimeout(20*time.Second),
@@ -304,6 +295,9 @@ client := nirvana.NewClient(
client.VMs.New(
context.TODO(),
vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -313,18 +307,12 @@ client.VMs.New(
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
},
option.WithMaxRetries(5),
)
diff --git a/api.md b/api.md
index 556cc5c..fd8746f 100644
--- a/api.md
+++ b/api.md
@@ -17,20 +17,12 @@ Params Types:
- vms.CPUParam
- vms.RamParam
-- vms.RamUnit
- vms.SSHKeyParam
-- vms.StorageParam
-- vms.StorageType
-- vms.StorageUnit
Response Types:
- vms.CPU
- vms.Ram
-- vms.RamUnit
-- vms.Storage
-- vms.StorageType
-- vms.StorageUnit
- vms.VM
- vms.VMListResponse
@@ -97,6 +89,15 @@ Methods:
# Volumes
+Params Types:
+
+- volumes.StorageType
+
+Response Types:
+
+- volumes.StorageType
+- volumes.Volume
+
Methods:
- client.Volumes.New(ctx context.Context, vmID string, body volumes.VolumeNewParams) (shared.Operation, error)
diff --git a/client_test.go b/client_test.go
index 8a20725..5684efd 100644
--- a/client_test.go
+++ b/client_test.go
@@ -40,6 +40,9 @@ func TestUserAgentHeader(t *testing.T) {
}),
)
client.VMs.New(context.Background(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -49,18 +52,12 @@ func TestUserAgentHeader(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if userAgent != fmt.Sprintf("NirvanaLabs/Go %s", internal.PackageVersion) {
t.Errorf("Expected User-Agent to be correct, but got: %#v", userAgent)
@@ -85,6 +82,9 @@ func TestRetryAfter(t *testing.T) {
}),
)
res, err := client.VMs.New(context.Background(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -94,18 +94,12 @@ func TestRetryAfter(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("Expected there to be a cancel error and for the response to be nil")
@@ -141,6 +135,9 @@ func TestDeleteRetryCountHeader(t *testing.T) {
option.WithHeaderDel("X-Stainless-Retry-Count"),
)
res, err := client.VMs.New(context.Background(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -150,18 +147,12 @@ func TestDeleteRetryCountHeader(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("Expected there to be a cancel error and for the response to be nil")
@@ -192,6 +183,9 @@ func TestOverwriteRetryCountHeader(t *testing.T) {
option.WithHeader("X-Stainless-Retry-Count", "42"),
)
res, err := client.VMs.New(context.Background(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -201,18 +195,12 @@ func TestOverwriteRetryCountHeader(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("Expected there to be a cancel error and for the response to be nil")
@@ -242,6 +230,9 @@ func TestRetryAfterMs(t *testing.T) {
}),
)
res, err := client.VMs.New(context.Background(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -251,18 +242,12 @@ func TestRetryAfterMs(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("Expected there to be a cancel error and for the response to be nil")
@@ -286,6 +271,9 @@ func TestContextCancel(t *testing.T) {
cancelCtx, cancel := context.WithCancel(context.Background())
cancel()
res, err := client.VMs.New(cancelCtx, vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -295,18 +283,12 @@ func TestContextCancel(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("Expected there to be a cancel error and for the response to be nil")
@@ -327,6 +309,9 @@ func TestContextCancelDelay(t *testing.T) {
cancelCtx, cancel := context.WithTimeout(context.Background(), 2*time.Millisecond)
defer cancel()
res, err := client.VMs.New(cancelCtx, vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -336,18 +321,12 @@ func TestContextCancelDelay(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("expected there to be a cancel error and for the response to be nil")
@@ -374,6 +353,9 @@ func TestContextDeadline(t *testing.T) {
}),
)
res, err := client.VMs.New(deadlineCtx, vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -383,18 +365,12 @@ func TestContextDeadline(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err == nil || res != nil {
t.Error("expected there to be a deadline error and for the response to be nil")
diff --git a/usage_test.go b/usage_test.go
index b060058..12d6993 100644
--- a/usage_test.go
+++ b/usage_test.go
@@ -27,6 +27,9 @@ func TestUsage(t *testing.T) {
option.WithAuthToken("My Auth Token"),
)
operation, err := client.VMs.New(context.TODO(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -36,18 +39,12 @@ func TestUsage(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- }}),
})
if err != nil {
t.Error(err)
diff --git a/vms/vm.go b/vms/vm.go
index ef9e519..592fb24 100644
--- a/vms/vm.go
+++ b/vms/vm.go
@@ -15,6 +15,7 @@ import (
"github.com/nirvana-labs/nirvana-go/internal/requestconfig"
"github.com/nirvana-labs/nirvana-go/option"
"github.com/nirvana-labs/nirvana-go/shared"
+ "github.com/nirvana-labs/nirvana-go/volumes"
"github.com/nirvana-labs/nirvana-go/vpcs"
)
@@ -124,16 +125,13 @@ func (r CPUParam) MarshalJSON() (data []byte, err error) {
// RAM details.
type Ram struct {
// RAM size
- Size int64 `json:"size,required"`
- // Unit (GB, MB, etc.)
- Unit RamUnit `json:"unit,required"`
+ Size int64 `json:"size,required"`
JSON ramJSON `json:"-"`
}
// ramJSON contains the JSON metadata for the struct [Ram]
type ramJSON struct {
Size apijson.Field
- Unit apijson.Field
raw string
ExtraFields map[string]apijson.Field
}
@@ -150,29 +148,12 @@ func (r ramJSON) RawJSON() string {
type RamParam struct {
// RAM size
Size param.Field[int64] `json:"size,required"`
- // Unit (GB, MB, etc.)
- Unit param.Field[RamUnit] `json:"unit,required"`
}
func (r RamParam) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
-// Unit (GB, MB, etc.)
-type RamUnit string
-
-const (
- RamUnitGB RamUnit = "GB"
-)
-
-func (r RamUnit) IsKnown() bool {
- switch r {
- case RamUnitGB:
- return true
- }
- return false
-}
-
// SSH key details.
type SSHKeyParam struct {
PublicKey param.Field[string] `json:"public_key,required"`
@@ -182,97 +163,22 @@ func (r SSHKeyParam) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
-// Storage details.
-type Storage struct {
- // Storage size
- Size int64 `json:"size,required"`
- // Storage type.
- Type StorageType `json:"type,required"`
- // Storage unit.
- Unit StorageUnit `json:"unit,required"`
- // Disk name, used later
- DiskName string `json:"disk_name"`
- JSON storageJSON `json:"-"`
-}
-
-// storageJSON contains the JSON metadata for the struct [Storage]
-type storageJSON struct {
- Size apijson.Field
- Type apijson.Field
- Unit apijson.Field
- DiskName apijson.Field
- raw string
- ExtraFields map[string]apijson.Field
-}
-
-func (r *Storage) UnmarshalJSON(data []byte) (err error) {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func (r storageJSON) RawJSON() string {
- return r.raw
-}
-
-// Storage details.
-type StorageParam struct {
- // Storage size
- Size param.Field[int64] `json:"size,required"`
- // Storage type.
- Type param.Field[StorageType] `json:"type,required"`
- // Storage unit.
- Unit param.Field[StorageUnit] `json:"unit,required"`
- // Disk name, used later
- DiskName param.Field[string] `json:"disk_name"`
-}
-
-func (r StorageParam) MarshalJSON() (data []byte, err error) {
- return apijson.MarshalRoot(r)
-}
-
-// Storage type.
-type StorageType string
-
-const (
- StorageTypeNvme StorageType = "nvme"
-)
-
-func (r StorageType) IsKnown() bool {
- switch r {
- case StorageTypeNvme:
- return true
- }
- return false
-}
-
-// Storage unit.
-type StorageUnit string
-
-const (
- StorageUnitGB StorageUnit = "GB"
-)
-
-func (r StorageUnit) IsKnown() bool {
- switch r {
- case StorageUnitGB:
- return true
- }
- return false
-}
-
// VM details.
type VM struct {
ID string `json:"id,required"`
+ // Volume details.
+ BootVolume volumes.Volume `json:"boot_volume,required"`
// CPU details.
- CPUConfig CPU `json:"cpu_config,required"`
- CreatedAt string `json:"created_at,required"`
+ CPUConfig CPU `json:"cpu_config,required"`
+ CreatedAt string `json:"created_at,required"`
+ DataVolumes []volumes.Volume `json:"data_volumes,required"`
// RAM details.
- MemConfig Ram `json:"mem_config,required"`
- Name string `json:"name,required"`
- PublicIP string `json:"public_ip,required"`
- Region shared.RegionName `json:"region,required"`
- Status shared.ResourceStatus `json:"status,required"`
- StorageConfig []Storage `json:"storage_config,required"`
- UpdatedAt string `json:"updated_at,required"`
+ MemConfig Ram `json:"mem_config,required"`
+ Name string `json:"name,required"`
+ PublicIP string `json:"public_ip,required"`
+ Region shared.RegionName `json:"region,required"`
+ Status shared.ResourceStatus `json:"status,required"`
+ UpdatedAt string `json:"updated_at,required"`
// VPC details.
VPC vpcs.VPC `json:"vpc,required"`
JSON vmJSON `json:"-"`
@@ -280,19 +186,20 @@ type VM struct {
// vmJSON contains the JSON metadata for the struct [VM]
type vmJSON struct {
- ID apijson.Field
- CPUConfig apijson.Field
- CreatedAt apijson.Field
- MemConfig apijson.Field
- Name apijson.Field
- PublicIP apijson.Field
- Region apijson.Field
- Status apijson.Field
- StorageConfig apijson.Field
- UpdatedAt apijson.Field
- VPC apijson.Field
- raw string
- ExtraFields map[string]apijson.Field
+ ID apijson.Field
+ BootVolume apijson.Field
+ CPUConfig apijson.Field
+ CreatedAt apijson.Field
+ DataVolumes apijson.Field
+ MemConfig apijson.Field
+ Name apijson.Field
+ PublicIP apijson.Field
+ Region apijson.Field
+ Status apijson.Field
+ UpdatedAt apijson.Field
+ VPC apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
}
func (r *VM) UnmarshalJSON(data []byte) (err error) {
@@ -324,6 +231,8 @@ func (r vmListResponseJSON) RawJSON() string {
}
type VMNewParams struct {
+ // Boot volume create request.
+ BootVolume param.Field[VMNewParamsBootVolume] `json:"boot_volume,required"`
// CPU details.
CPU param.Field[CPUParam] `json:"cpu,required"`
Name param.Field[string] `json:"name,required"`
@@ -335,27 +244,69 @@ type VMNewParams struct {
Region param.Field[shared.RegionName] `json:"region,required"`
SourceAddress param.Field[string] `json:"source_address,required"`
// SSH key details.
- SSHKey param.Field[SSHKeyParam] `json:"ssh_key,required"`
- Storage param.Field[[]StorageParam] `json:"storage,required"`
- SubnetID param.Field[string] `json:"subnet_id"`
+ SSHKey param.Field[SSHKeyParam] `json:"ssh_key,required"`
+ DataVolumes param.Field[[]VMNewParamsDataVolume] `json:"data_volumes"`
+ SubnetID param.Field[string] `json:"subnet_id"`
}
func (r VMNewParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
+// Boot volume create request.
+type VMNewParamsBootVolume struct {
+ Size param.Field[int64] `json:"size,required"`
+}
+
+func (r VMNewParamsBootVolume) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+// Data volume create request.
+type VMNewParamsDataVolume struct {
+ Size param.Field[int64] `json:"size,required"`
+ // Storage type.
+ Type param.Field[volumes.StorageType] `json:"type"`
+}
+
+func (r VMNewParamsDataVolume) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
type VMUpdateParams struct {
+ // Boot volume create request.
+ BootVolume param.Field[VMUpdateParamsBootVolume] `json:"boot_volume"`
// CPU details.
- CPU param.Field[CPUParam] `json:"cpu"`
+ CPU param.Field[CPUParam] `json:"cpu"`
+ DataVolumes param.Field[[]VMUpdateParamsDataVolume] `json:"data_volumes"`
// RAM details.
- Ram param.Field[RamParam] `json:"ram"`
- Storage param.Field[[]StorageParam] `json:"storage"`
+ Ram param.Field[RamParam] `json:"ram"`
}
func (r VMUpdateParams) MarshalJSON() (data []byte, err error) {
return apijson.MarshalRoot(r)
}
+// Boot volume create request.
+type VMUpdateParamsBootVolume struct {
+ Size param.Field[int64] `json:"size,required"`
+}
+
+func (r VMUpdateParamsBootVolume) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
+// Data volume create request.
+type VMUpdateParamsDataVolume struct {
+ Size param.Field[int64] `json:"size,required"`
+ // Storage type.
+ Type param.Field[volumes.StorageType] `json:"type"`
+}
+
+func (r VMUpdateParamsDataVolume) MarshalJSON() (data []byte, err error) {
+ return apijson.MarshalRoot(r)
+}
+
type VMListParams struct {
// Region
Region param.Field[string] `query:"region,required"`
diff --git a/vms/vm_test.go b/vms/vm_test.go
index 3c7d61b..943e414 100644
--- a/vms/vm_test.go
+++ b/vms/vm_test.go
@@ -13,6 +13,7 @@ import (
"github.com/nirvana-labs/nirvana-go/option"
"github.com/nirvana-labs/nirvana-go/shared"
"github.com/nirvana-labs/nirvana-go/vms"
+ "github.com/nirvana-labs/nirvana-go/volumes"
)
func TestVMNewWithOptionalParams(t *testing.T) {
@@ -28,6 +29,9 @@ func TestVMNewWithOptionalParams(t *testing.T) {
option.WithAuthToken("My Auth Token"),
)
_, err := client.VMs.New(context.TODO(), vms.VMNewParams{
+ BootVolume: nirvana.F(vms.VMNewParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
@@ -37,18 +41,15 @@ func TestVMNewWithOptionalParams(t *testing.T) {
Ports: nirvana.F([]string{"22", "80", "443"}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
Region: nirvana.F(shared.RegionNameAmsterdam),
SourceAddress: nirvana.F("0.0.0.0/0"),
SSHKey: nirvana.F(vms.SSHKeyParam{
PublicKey: nirvana.F("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC1234567890"),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- DiskName: nirvana.F("disk_name"),
+ DataVolumes: nirvana.F([]vms.VMNewParamsDataVolume{{
+ Size: nirvana.F(int64(100)),
+ Type: nirvana.F(volumes.StorageTypeNvme),
}}),
SubnetID: nirvana.F("123e4567-e89b-12d3-a456-426614174000"),
})
@@ -77,19 +78,19 @@ func TestVMUpdateWithOptionalParams(t *testing.T) {
context.TODO(),
"vm_id",
vms.VMUpdateParams{
+ BootVolume: nirvana.F(vms.VMUpdateParamsBootVolume{
+ Size: nirvana.F(int64(100)),
+ }),
CPU: nirvana.F(vms.CPUParam{
Cores: nirvana.F(int64(2)),
}),
+ DataVolumes: nirvana.F([]vms.VMUpdateParamsDataVolume{{
+ Size: nirvana.F(int64(100)),
+ Type: nirvana.F(volumes.StorageTypeNvme),
+ }}),
Ram: nirvana.F(vms.RamParam{
Size: nirvana.F(int64(2)),
- Unit: nirvana.F(vms.RamUnitGB),
}),
- Storage: nirvana.F([]vms.StorageParam{{
- Size: nirvana.F(int64(100)),
- Type: nirvana.F(vms.StorageTypeNvme),
- Unit: nirvana.F(vms.StorageUnitGB),
- DiskName: nirvana.F("disk_name"),
- }}),
},
)
if err != nil {
diff --git a/volumes/volume.go b/volumes/volume.go
index 75004b1..78d78bc 100644
--- a/volumes/volume.go
+++ b/volumes/volume.go
@@ -62,8 +62,51 @@ func (r *VolumeService) Delete(ctx context.Context, vmID string, volumeID string
return
}
+// Storage type.
+type StorageType string
+
+const (
+ StorageTypeNvme StorageType = "nvme"
+)
+
+func (r StorageType) IsKnown() bool {
+ switch r {
+ case StorageTypeNvme:
+ return true
+ }
+ return false
+}
+
+// Volume details.
+type Volume struct {
+ ID string `json:"id,required"`
+ Size int64 `json:"size,required"`
+ // Storage type.
+ Type StorageType `json:"type,required"`
+ JSON volumeJSON `json:"-"`
+}
+
+// volumeJSON contains the JSON metadata for the struct [Volume]
+type volumeJSON struct {
+ ID apijson.Field
+ Size apijson.Field
+ Type apijson.Field
+ raw string
+ ExtraFields map[string]apijson.Field
+}
+
+func (r *Volume) UnmarshalJSON(data []byte) (err error) {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func (r volumeJSON) RawJSON() string {
+ return r.raw
+}
+
type VolumeNewParams struct {
Size param.Field[int64] `json:"size,required"`
+ // Storage type.
+ Type param.Field[StorageType] `json:"type"`
}
func (r VolumeNewParams) MarshalJSON() (data []byte, err error) {
diff --git a/volumes/volume_test.go b/volumes/volume_test.go
index 5359427..21bd459 100644
--- a/volumes/volume_test.go
+++ b/volumes/volume_test.go
@@ -14,7 +14,7 @@ import (
"github.com/nirvana-labs/nirvana-go/volumes"
)
-func TestVolumeNew(t *testing.T) {
+func TestVolumeNewWithOptionalParams(t *testing.T) {
baseURL := "http://localhost:4010"
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
baseURL = envURL
@@ -31,6 +31,7 @@ func TestVolumeNew(t *testing.T) {
"vm_id",
volumes.VolumeNewParams{
Size: nirvana.F(int64(100)),
+ Type: nirvana.F(volumes.StorageTypeNvme),
},
)
if err != nil {