diff --git a/.release-please-manifest.json b/.release-please-manifest.json index ee49ac2..fd0ccba 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.1.0-alpha.11" + ".": "0.1.0-alpha.12" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index b9a817c..b80f985 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-6aab21baffe1788ef3489dedfb817e9425a87edc3955e0b9cf720cca4302d7a3.yml +configured_endpoints: 20 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/nirvana-labs%2Fnirvana-88eef6692dd2f29d0734587b0a255ce12fff9fa28b6c1d66d2b61364d2d0c311.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index db83979..919d618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.1.0-alpha.12 (2025-01-23) + +Full Changelog: [v0.1.0-alpha.11...v0.1.0-alpha.12](https://github.com/nirvana-labs/nirvana-go/compare/v0.1.0-alpha.11...v0.1.0-alpha.12) + +### Features + +* **api:** api update ([#39](https://github.com/nirvana-labs/nirvana-go/issues/39)) ([73233e3](https://github.com/nirvana-labs/nirvana-go/commit/73233e391f52116d4a734a357b2536475de1f420)) +* **api:** api update ([#41](https://github.com/nirvana-labs/nirvana-go/issues/41)) ([93d1e94](https://github.com/nirvana-labs/nirvana-go/commit/93d1e948df9848173a6d7f503ba07ff2cc0a372d)) +* **api:** api update ([#42](https://github.com/nirvana-labs/nirvana-go/issues/42)) ([b8afef7](https://github.com/nirvana-labs/nirvana-go/commit/b8afef7cb36a5a8b2114c145f2bf8e7a2102b643)) +* **api:** api update ([#43](https://github.com/nirvana-labs/nirvana-go/issues/43)) ([14f64e8](https://github.com/nirvana-labs/nirvana-go/commit/14f64e83f6ddb23a481e6e428441d989a573361d)) +* **api:** api update ([#44](https://github.com/nirvana-labs/nirvana-go/issues/44)) ([c8a1811](https://github.com/nirvana-labs/nirvana-go/commit/c8a1811058837b60cdc10ab6ac1a5136bb886a66)) +* **api:** api update ([#45](https://github.com/nirvana-labs/nirvana-go/issues/45)) ([0274f77](https://github.com/nirvana-labs/nirvana-go/commit/0274f7788f0f15e1bee3a446db5802bae0fffdec)) + ## 0.1.0-alpha.11 (2025-01-22) Full Changelog: [v0.1.0-alpha.10...v0.1.0-alpha.11](https://github.com/nirvana-labs/nirvana-go/compare/v0.1.0-alpha.10...v0.1.0-alpha.11) diff --git a/README.md b/README.md index 4e12afa..bdc9dcb 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Or to pin the version: ```sh -go get -u 'github.com/nirvana-labs/nirvana-go@v0.1.0-alpha.11' +go get -u 'github.com/nirvana-labs/nirvana-go@v0.1.0-alpha.12' ``` @@ -61,7 +61,7 @@ func main() { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -202,7 +202,7 @@ _, err := client.VMs.New(context.TODO(), vms.VMNewParams{ }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -248,7 +248,7 @@ client.VMs.New( }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -303,7 +303,7 @@ client.VMs.New( }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), diff --git a/api.md b/api.md index ce80cad..353f905 100644 --- a/api.md +++ b/api.md @@ -18,6 +18,7 @@ Params Types: Response Types: - vms.CPU +- vms.OSImage - vms.Ram - vms.VM - vms.VMList @@ -30,6 +31,12 @@ Methods: - client.VMs.Delete(ctx context.Context, vmID string) (operations.Operation, error) - client.VMs.Get(ctx context.Context, vmID string) (vms.VM, error) +## OSImages + +Methods: + +- client.VMs.OSImages.List(ctx context.Context) ([]vms.OSImage, error) + # VPCs Response Types: @@ -78,9 +85,9 @@ Response Types: Methods: -- client.Volumes.New(ctx context.Context, vmID string, body volumes.VolumeNewParams) (operations.Operation, error) -- client.Volumes.Update(ctx context.Context, vmID string, volumeID string, body volumes.VolumeUpdateParams) (operations.Operation, error) -- client.Volumes.Delete(ctx context.Context, vmID string, volumeID string) (operations.Operation, error) +- client.Volumes.New(ctx context.Context, body volumes.VolumeNewParams) (operations.Operation, error) +- client.Volumes.Update(ctx context.Context, volumeID string, body volumes.VolumeUpdateParams) (operations.Operation, error) +- client.Volumes.Delete(ctx context.Context, volumeID string, body volumes.VolumeDeleteParams) (operations.Operation, error) # Operations diff --git a/client_test.go b/client_test.go index 5684efd..4096aff 100644 --- a/client_test.go +++ b/client_test.go @@ -48,7 +48,7 @@ func TestUserAgentHeader(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -90,7 +90,7 @@ func TestRetryAfter(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -143,7 +143,7 @@ func TestDeleteRetryCountHeader(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -191,7 +191,7 @@ func TestOverwriteRetryCountHeader(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -238,7 +238,7 @@ func TestRetryAfterMs(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -279,7 +279,7 @@ func TestContextCancel(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -317,7 +317,7 @@ func TestContextCancelDelay(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), @@ -361,7 +361,7 @@ func TestContextDeadline(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), diff --git a/internal/version.go b/internal/version.go index dec22ba..4cd53ff 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.1.0-alpha.11" // x-release-please-version +const PackageVersion = "0.1.0-alpha.12" // x-release-please-version diff --git a/usage_test.go b/usage_test.go index 12d6993..2a80e9f 100644 --- a/usage_test.go +++ b/usage_test.go @@ -35,7 +35,7 @@ func TestUsage(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), diff --git a/vms/osimage.go b/vms/osimage.go new file mode 100644 index 0000000..1256b72 --- /dev/null +++ b/vms/osimage.go @@ -0,0 +1,38 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package vms + +import ( + "context" + "net/http" + + "github.com/nirvana-labs/nirvana-go/internal/requestconfig" + "github.com/nirvana-labs/nirvana-go/option" +) + +// OSImageService contains methods and other services that help with interacting +// with the Nirvana Labs API. +// +// Note, unlike clients, this service does not read variables from the environment +// automatically. You should not instantiate this service directly, and instead use +// the [NewOSImageService] method instead. +type OSImageService struct { + Options []option.RequestOption +} + +// NewOSImageService generates a new service that applies the given options to each +// request. These options are applied after the parent client's options (if there +// is one), and before any request-specific options. +func NewOSImageService(opts ...option.RequestOption) (r *OSImageService) { + r = &OSImageService{} + r.Options = opts + return +} + +// List all OS Images +func (r *OSImageService) List(ctx context.Context, opts ...option.RequestOption) (res *[]OSImage, err error) { + opts = append(r.Options[:], opts...) + path := "vms/os_images" + err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) + return +} diff --git a/vms/osimage_test.go b/vms/osimage_test.go new file mode 100644 index 0000000..f2eb926 --- /dev/null +++ b/vms/osimage_test.go @@ -0,0 +1,36 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +package vms_test + +import ( + "context" + "errors" + "os" + "testing" + + "github.com/nirvana-labs/nirvana-go" + "github.com/nirvana-labs/nirvana-go/internal/testutil" + "github.com/nirvana-labs/nirvana-go/option" +) + +func TestOSImageList(t *testing.T) { + baseURL := "http://localhost:4010" + if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok { + baseURL = envURL + } + if !testutil.CheckTestServer(t, baseURL) { + return + } + client := nirvana.NewClient( + option.WithBaseURL(baseURL), + option.WithAuthToken("My Auth Token"), + ) + _, err := client.VMs.OSImages.List(context.TODO()) + if err != nil { + var apierr *nirvana.Error + if errors.As(err, &apierr) { + t.Log(string(apierr.DumpRequest(true))) + } + t.Fatalf("err should be nil: %s", err.Error()) + } +} diff --git a/vms/vm.go b/vms/vm.go index 6d7fdee..5a10c75 100644 --- a/vms/vm.go +++ b/vms/vm.go @@ -15,7 +15,6 @@ import ( "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" ) // VMService contains methods and other services that help with interacting with @@ -25,7 +24,8 @@ import ( // automatically. You should not instantiate this service directly, and instead use // the [NewVMService] method instead. type VMService struct { - Options []option.RequestOption + Options []option.RequestOption + OSImages *OSImageService } // NewVMService generates a new service that applies the given options to each @@ -34,6 +34,7 @@ type VMService struct { func NewVMService(opts ...option.RequestOption) (r *VMService) { r = &VMService{} r.Options = opts + r.OSImages = NewOSImageService(opts...) return } @@ -119,6 +120,30 @@ func (r CPUParam) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } +type OSImage struct { + CreatedAt string `json:"created_at,required"` + DisplayName string `json:"display_name,required"` + Name string `json:"name,required"` + JSON osImageJSON `json:"-"` +} + +// osImageJSON contains the JSON metadata for the struct [OSImage] +type osImageJSON struct { + CreatedAt apijson.Field + DisplayName apijson.Field + Name apijson.Field + raw string + ExtraFields map[string]apijson.Field +} + +func (r *OSImage) UnmarshalJSON(data []byte) (err error) { + return apijson.UnmarshalRoot(data, r) +} + +func (r osImageJSON) RawJSON() string { + return r.raw +} + // RAM details. type Ram struct { // RAM size @@ -176,9 +201,8 @@ type VM struct { 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:"-"` + VPCID string `json:"vpc_id,required"` + JSON vmJSON `json:"-"` } // vmJSON contains the JSON metadata for the struct [VM] @@ -194,7 +218,7 @@ type vmJSON struct { Region apijson.Field Status apijson.Field UpdatedAt apijson.Field - VPC apijson.Field + VPCID apijson.Field raw string ExtraFields map[string]apijson.Field } @@ -234,7 +258,7 @@ type VMNewParams struct { CPU param.Field[CPUParam] `json:"cpu,required"` Name param.Field[string] `json:"name,required"` NeedPublicIP param.Field[bool] `json:"need_public_ip,required"` - OsImageID param.Field[int64] `json:"os_image_id,required"` + OSImageName param.Field[string] `json:"os_image_name,required"` Ports param.Field[[]string] `json:"ports,required"` // RAM details. Ram param.Field[RamParam] `json:"ram,required"` @@ -259,7 +283,7 @@ func (r VMNewParamsBootVolume) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } -// Data volume create request. +// VM data volume create request. type VMNewParamsDataVolume struct { Size param.Field[int64] `json:"size,required"` // Storage type. @@ -293,7 +317,7 @@ func (r VMUpdateParamsBootVolume) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } -// Data volume create request. +// VM data volume create request. type VMUpdateParamsDataVolume struct { Size param.Field[int64] `json:"size,required"` // Storage type. diff --git a/vms/vm_test.go b/vms/vm_test.go index 967bfa6..ae25ed3 100644 --- a/vms/vm_test.go +++ b/vms/vm_test.go @@ -37,7 +37,7 @@ func TestVMNewWithOptionalParams(t *testing.T) { }), Name: nirvana.F("my-vm"), NeedPublicIP: nirvana.F(true), - OsImageID: nirvana.F(int64(1)), + OSImageName: nirvana.F("noble-2024-12-06"), Ports: nirvana.F([]string{"22", "80", "443"}), Ram: nirvana.F(vms.RamParam{ Size: nirvana.F(int64(2)), diff --git a/volumes/volume.go b/volumes/volume.go index 57cfef6..4840b8c 100644 --- a/volumes/volume.go +++ b/volumes/volume.go @@ -34,47 +34,35 @@ func NewVolumeService(opts ...option.RequestOption) (r *VolumeService) { return } -// Create a Volume -func (r *VolumeService) New(ctx context.Context, vmID string, body VolumeNewParams, opts ...option.RequestOption) (res *operations.Operation, err error) { +// Create a Volume. Only data volumes can be created. +func (r *VolumeService) New(ctx context.Context, body VolumeNewParams, opts ...option.RequestOption) (res *operations.Operation, err error) { opts = append(r.Options[:], opts...) - if vmID == "" { - err = errors.New("missing required vm_id parameter") - return - } - path := fmt.Sprintf("vms/%s/volumes", vmID) + path := "volumes" err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...) return } -// Update a volume -func (r *VolumeService) Update(ctx context.Context, vmID string, volumeID string, body VolumeUpdateParams, opts ...option.RequestOption) (res *operations.Operation, err error) { +// Update a Volume. Boot or data volumes can be updated. +func (r *VolumeService) Update(ctx context.Context, volumeID string, body VolumeUpdateParams, opts ...option.RequestOption) (res *operations.Operation, err error) { opts = append(r.Options[:], opts...) - if vmID == "" { - err = errors.New("missing required vm_id parameter") - return - } if volumeID == "" { err = errors.New("missing required volume_id parameter") return } - path := fmt.Sprintf("vms/%s/volumes/%s", vmID, volumeID) + path := fmt.Sprintf("volumes/%s", volumeID) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) return } -// Delete a volume -func (r *VolumeService) Delete(ctx context.Context, vmID string, volumeID string, opts ...option.RequestOption) (res *operations.Operation, err error) { +// Delete a Volume. Boot or data volumes can be deleted. +func (r *VolumeService) Delete(ctx context.Context, volumeID string, body VolumeDeleteParams, opts ...option.RequestOption) (res *operations.Operation, err error) { opts = append(r.Options[:], opts...) - if vmID == "" { - err = errors.New("missing required vm_id parameter") - return - } if volumeID == "" { err = errors.New("missing required volume_id parameter") return } - path := fmt.Sprintf("vms/%s/volumes/%s", vmID, volumeID) - err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...) + path := fmt.Sprintf("volumes/%s", volumeID) + err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, body, &res, opts...) return } @@ -120,7 +108,8 @@ func (r volumeJSON) RawJSON() string { } type VolumeNewParams struct { - Size param.Field[int64] `json:"size,required"` + Size param.Field[int64] `json:"size,required"` + VMID param.Field[string] `json:"vm_id,required"` // Storage type. Type param.Field[StorageType] `json:"type"` } @@ -130,9 +119,18 @@ func (r VolumeNewParams) MarshalJSON() (data []byte, err error) { } type VolumeUpdateParams struct { - Size param.Field[int64] `json:"size,required"` + Size param.Field[int64] `json:"size,required"` + VMID param.Field[string] `json:"vm_id,required"` } func (r VolumeUpdateParams) MarshalJSON() (data []byte, err error) { return apijson.MarshalRoot(r) } + +type VolumeDeleteParams struct { + VMID param.Field[string] `json:"vm_id,required"` +} + +func (r VolumeDeleteParams) MarshalJSON() (data []byte, err error) { + return apijson.MarshalRoot(r) +} diff --git a/volumes/volume_test.go b/volumes/volume_test.go index d01af94..72c70a7 100644 --- a/volumes/volume_test.go +++ b/volumes/volume_test.go @@ -26,14 +26,11 @@ func TestVolumeNewWithOptionalParams(t *testing.T) { option.WithBaseURL(baseURL), option.WithAuthToken("My Auth Token"), ) - _, err := client.Volumes.New( - context.TODO(), - "vm_id", - volumes.VolumeNewParams{ - Size: nirvana.F(int64(100)), - Type: nirvana.F(volumes.StorageTypeNvme), - }, - ) + _, err := client.Volumes.New(context.TODO(), volumes.VolumeNewParams{ + Size: nirvana.F(int64(100)), + VMID: nirvana.F("vm_id"), + Type: nirvana.F(volumes.StorageTypeNvme), + }) if err != nil { var apierr *nirvana.Error if errors.As(err, &apierr) { @@ -57,10 +54,10 @@ func TestVolumeUpdate(t *testing.T) { ) _, err := client.Volumes.Update( context.TODO(), - "vm_id", "volume_id", volumes.VolumeUpdateParams{ Size: nirvana.F(int64(100)), + VMID: nirvana.F("vm_id"), }, ) if err != nil { @@ -86,8 +83,10 @@ func TestVolumeDelete(t *testing.T) { ) _, err := client.Volumes.Delete( context.TODO(), - "vm_id", "volume_id", + volumes.VolumeDeleteParams{ + VMID: nirvana.F("vm_id"), + }, ) if err != nil { var apierr *nirvana.Error