Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8392db9ae3 |
@@ -45,6 +45,11 @@ func (s *PricingService) EstimateInstance(ctx context.Context, region string, in
|
|||||||
err := s.client.do(ctx, http.MethodPost, "/regions/"+escaped(region)+"/price-estimate", input, &result, newID())
|
err := s.client.do(ctx, http.MethodPost, "/regions/"+escaped(region)+"/price-estimate", input, &result, newID())
|
||||||
return &result, err
|
return &result, err
|
||||||
}
|
}
|
||||||
|
func (s *PricingService) EstimateExistingInstance(ctx context.Context, region, instanceID string) (*PriceEstimate, error) {
|
||||||
|
var result PriceEstimate
|
||||||
|
err := s.client.do(ctx, http.MethodPost, instancesPath(region, instanceID)+"/price-estimate", map[string]any{}, &result, "")
|
||||||
|
return &result, err
|
||||||
|
}
|
||||||
func catalogPath(region, resource string, options ListOptions) string {
|
func catalogPath(region, resource string, options ListOptions) string {
|
||||||
values := url.Values{}
|
values := url.Values{}
|
||||||
if options.Query != "" {
|
if options.Query != "" {
|
||||||
|
|||||||
@@ -106,3 +106,35 @@ func TestListQueryParametersAreNotEscapedIntoPath(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRuntimePricingAndInstanceEIPOperations(t *testing.T) {
|
||||||
|
paths := []string{}
|
||||||
|
client, _ := testClient(t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
paths = append(paths, r.Method+" "+r.URL.Path)
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
if r.URL.Path == "/api/sdk/v1/regions/us-east-1/instances/local-1/price-estimate" {
|
||||||
|
_, _ = w.Write([]byte(`{"code":200,"message":"Success","data":{"currency":"USD","monthly_price":12.5,"configuration_fingerprint":"fingerprint"}}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _ = w.Write([]byte(`{"code":202,"message":"Accepted","data":{"task_id":"task-1","status":"queued"}}`))
|
||||||
|
})
|
||||||
|
estimate, err := client.Pricing.EstimateExistingInstance(context.Background(), "us-east-1", "local-1")
|
||||||
|
if err != nil || estimate.ConfigurationFingerprint != "fingerprint" || estimate.MonthlyPrice != 12.5 {
|
||||||
|
t.Fatalf("estimate=%#v err=%v", estimate, err)
|
||||||
|
}
|
||||||
|
if _, err := client.EIPs.Disassociate(context.Background(), "us-east-1", "local-1", WithIdempotencyKey("disassociate")); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := client.EIPs.Release(context.Background(), "us-east-1", "local-1", WithIdempotencyKey("release")); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
want := []string{"POST /api/sdk/v1/regions/us-east-1/instances/local-1/price-estimate", "POST /api/sdk/v1/regions/us-east-1/instances/local-1/eip/disassociate", "DELETE /api/sdk/v1/regions/us-east-1/instances/local-1/eip"}
|
||||||
|
if len(paths) != len(want) {
|
||||||
|
t.Fatalf("paths=%v", paths)
|
||||||
|
}
|
||||||
|
for i := range want {
|
||||||
|
if paths[i] != want[i] {
|
||||||
|
t.Fatalf("paths=%v want=%v", paths, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+10
-2
@@ -51,6 +51,12 @@ func (s *EIPService) Get(ctx context.Context, region, instanceID string) (*EIPIn
|
|||||||
func (s *EIPService) Ensure(ctx context.Context, region, instanceID string, input EnsureEIPRequest, options ...RequestOption) (*Operation, error) {
|
func (s *EIPService) Ensure(ctx context.Context, region, instanceID string, input EnsureEIPRequest, options ...RequestOption) (*Operation, error) {
|
||||||
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPost, instancesPath(region, instanceID)+"/eip", input, options...)
|
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPost, instancesPath(region, instanceID)+"/eip", input, options...)
|
||||||
}
|
}
|
||||||
|
func (s *EIPService) Disassociate(ctx context.Context, region, instanceID string, options ...RequestOption) (*Operation, error) {
|
||||||
|
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPost, instancesPath(region, instanceID)+"/eip/disassociate", map[string]any{}, options...)
|
||||||
|
}
|
||||||
|
func (s *EIPService) Release(ctx context.Context, region, instanceID string, options ...RequestOption) (*Operation, error) {
|
||||||
|
return (&InstancesService{client: s.client}).operation(ctx, http.MethodDelete, instancesPath(region, instanceID)+"/eip", map[string]any{}, options...)
|
||||||
|
}
|
||||||
func (s *EIPService) SetReverseDNS(ctx context.Context, region, instanceID string, input ReverseDNSRequest, options ...RequestOption) (*Operation, error) {
|
func (s *EIPService) SetReverseDNS(ctx context.Context, region, instanceID string, input ReverseDNSRequest, options ...RequestOption) (*Operation, error) {
|
||||||
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPatch, instancesPath(region, instanceID)+"/eip/reverse-dns", input, options...)
|
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPatch, instancesPath(region, instanceID)+"/eip/reverse-dns", input, options...)
|
||||||
}
|
}
|
||||||
@@ -79,9 +85,11 @@ type ModifyVolumeRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *VolumeService) List(ctx context.Context, region, instanceID string) ([]Volume, error) {
|
func (s *VolumeService) List(ctx context.Context, region, instanceID string) ([]Volume, error) {
|
||||||
var result []Volume
|
var result struct {
|
||||||
|
Items []Volume `json:"items"`
|
||||||
|
}
|
||||||
err := s.client.do(ctx, http.MethodGet, instancesPath(region, instanceID)+"/volumes", nil, &result, "")
|
err := s.client.do(ctx, http.MethodGet, instancesPath(region, instanceID)+"/volumes", nil, &result, "")
|
||||||
return result, err
|
return result.Items, err
|
||||||
}
|
}
|
||||||
func (s *VolumeService) Create(ctx context.Context, region, instanceID string, input CreateVolumeRequest, options ...RequestOption) (*Operation, error) {
|
func (s *VolumeService) Create(ctx context.Context, region, instanceID string, input CreateVolumeRequest, options ...RequestOption) (*Operation, error) {
|
||||||
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPost, instancesPath(region, instanceID)+"/volumes", input, options...)
|
return (&InstancesService{client: s.client}).operation(ctx, http.MethodPost, instancesPath(region, instanceID)+"/volumes", input, options...)
|
||||||
|
|||||||
@@ -112,12 +112,14 @@ type CreateInstanceRequest struct {
|
|||||||
TrafficLimitGiB *float64 `json:"traffic_limit_gib,omitempty"`
|
TrafficLimitGiB *float64 `json:"traffic_limit_gib,omitempty"`
|
||||||
}
|
}
|
||||||
type PriceEstimate struct {
|
type PriceEstimate struct {
|
||||||
Currency string `json:"currency"`
|
Currency string `json:"currency"`
|
||||||
HourlyPrice float64 `json:"hourly_price"`
|
HourlyPrice float64 `json:"hourly_price"`
|
||||||
MonthlyPrice float64 `json:"monthly_price"`
|
MonthlyPrice float64 `json:"monthly_price"`
|
||||||
CalendarMonthPrice float64 `json:"calendar_month_price"`
|
CalendarMonthPrice float64 `json:"calendar_month_price"`
|
||||||
Breakdown map[string]any `json:"breakdown"`
|
Breakdown map[string]any `json:"breakdown"`
|
||||||
Raw map[string]any `json:"-"`
|
ConfigurationFingerprint string `json:"configuration_fingerprint,omitempty"`
|
||||||
|
ResourceSyncedAt time.Time `json:"resource_synced_at,omitempty"`
|
||||||
|
Raw map[string]any `json:"-"`
|
||||||
}
|
}
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|||||||
Reference in New Issue
Block a user