From af9d6575f5c1b80018b9008fcd9e82c8170a3012 Mon Sep 17 00:00:00 2001 From: Aditya Saha Date: Tue, 22 Oct 2024 13:20:31 -0400 Subject: [PATCH] Adjust public api model --- droplet_autoscaler.go | 258 ----------------- droplet_autoscaler_test.go | 565 ------------------------------------- 2 files changed, 823 deletions(-) delete mode 100644 droplet_autoscaler.go delete mode 100644 droplet_autoscaler_test.go diff --git a/droplet_autoscaler.go b/droplet_autoscaler.go deleted file mode 100644 index 9a27a236..00000000 --- a/droplet_autoscaler.go +++ /dev/null @@ -1,258 +0,0 @@ -package godo - -import ( - "context" - "fmt" - "net/http" - "time" -) - -const ( - dropletAutoscaleBasePath = "/v2/droplets/autoscale" -) - -// DropletAutoscaleService defines an interface for managing droplet autoscale pools through DigitalOcean API -type DropletAutoscaleService interface { - Create(context.Context, *DropletAutoscalePoolRequest) (string, *Response, error) - Get(context.Context, string) (*DropletAutoscalePool, *Response, error) - List(context.Context, *ListOptions) ([]*DropletAutoscalePool, *Response, error) - ListMembers(context.Context, string, *ListOptions) ([]*DropletAutoscaleResource, *Response, error) - ListHistory(context.Context, string, *ListOptions) ([]*DropletAutoscaleHistoryEvent, *Response, error) - Update(context.Context, string, *DropletAutoscalePoolRequest) (string, *Response, error) - Delete(context.Context, string) (*Response, error) - DeleteDangerous(context.Context, string) (*Response, error) -} - -// DropletAutoscalePool represents a DigitalOcean droplet autoscale pool -type DropletAutoscalePool struct { - ID string `json:"id"` - Name string `json:"name"` - Config *DropletAutoscaleConfiguration `json:"config"` - DropletTemplate *DropletAutoscaleResourceTemplate `json:"droplet_template"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - CurrentUtilization *DropletAutoscaleResourceUtilization `json:"current_utilization,omitempty"` - Status string `json:"status"` -} - -// DropletAutoscaleConfiguration represents a DigitalOcean droplet autoscale pool configuration -type DropletAutoscaleConfiguration struct { - MinInstances uint64 `json:"min_instances,omitempty"` - MaxInstances uint64 `json:"max_instances,omitempty"` - TargetCPUUtilization float64 `json:"target_cpu_utilization,omitempty"` - TargetMemoryUtilization float64 `json:"target_memory_utilization,omitempty"` - CooldownMinutes uint32 `json:"cooldown_minutes,omitempty"` - TargetNumberInstances uint64 `json:"target_number_instances,omitempty"` -} - -// DropletAutoscaleResourceTemplate represents a DigitalOcean droplet autoscale pool resource template -type DropletAutoscaleResourceTemplate struct { - Size string `json:"size"` - Region string `json:"region"` - Image string `json:"image"` - Tags []string `json:"tags"` - SSHKeys []string `json:"ssh_keys"` - VpcUUID string `json:"vpc_uuid"` - WithDropletAgent bool `json:"with_droplet_agent"` - ProjectID string `json:"project_id"` - IPV6 bool `json:"ipv6"` - UserData string `json:"user_data"` -} - -// DropletAutoscaleResourceUtilization represents a DigitalOcean droplet autoscale pool resource utilization -type DropletAutoscaleResourceUtilization struct { - Memory float64 `json:"memory,omitempty"` - CPU float64 `json:"cpu,omitempty"` -} - -// DropletAutoscaleResource represents a DigitalOcean droplet autoscale pool resource -type DropletAutoscaleResource struct { - DropletID uint64 `json:"droplet_id"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - HealthStatus string `json:"health_status"` - UnhealthyReason string `json:"unhealthy_reason,omitempty"` - Status string `json:"status"` - CurrentUtilization *DropletAutoscaleResourceUtilization `json:"current_utilization,omitempty"` -} - -// DropletAutoscaleHistoryEvent represents a DigitalOcean droplet autoscale pool history event -type DropletAutoscaleHistoryEvent struct { - HistoryEventID string `json:"history_event_id"` - CurrentInstanceCount uint64 `json:"current_instance_count"` - DesiredInstanceCount uint64 `json:"desired_instance_count"` - Reason string `json:"reason"` - Status string `json:"status"` - ErrorReason string `json:"error_reason,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} - -// DropletAutoscalePoolRequest represents a DigitalOcean droplet autoscale pool create/update request -type DropletAutoscalePoolRequest struct { - Name string `json:"name"` - Config *DropletAutoscaleConfiguration `json:"config"` - DropletTemplate *DropletAutoscaleResourceTemplate `json:"droplet_template"` -} - -type dropletAutoscalePoolRoot struct { - ID string `json:"id"` -} - -type dropletAutoscalePoolsRoot struct { - AutoscalePools []*DropletAutoscalePool `json:"autoscale_pools"` - Links *Links `json:"links"` - Meta *Meta `json:"meta"` -} - -type dropletAutoscaleMembersRoot struct { - Droplets []*DropletAutoscaleResource `json:"droplets"` - Links *Links `json:"links"` - Meta *Meta `json:"meta"` -} - -type dropletAutoscaleHistoryEventsRoot struct { - History []*DropletAutoscaleHistoryEvent `json:"history"` - Links *Links `json:"links"` - Meta *Meta `json:"meta"` -} - -// DropletAutoscaleServiceOp handles communication with droplet autoscale-related methods of the DigitalOcean API -type DropletAutoscaleServiceOp struct { - client *Client -} - -var _ DropletAutoscaleService = &DropletAutoscaleServiceOp{} - -// Create a new droplet autoscale pool -func (d *DropletAutoscaleServiceOp) Create(ctx context.Context, createReq *DropletAutoscalePoolRequest) (string, *Response, error) { - req, err := d.client.NewRequest(ctx, http.MethodPost, dropletAutoscaleBasePath, createReq) - if err != nil { - return "", nil, err - } - root := new(dropletAutoscalePoolRoot) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return "", nil, err - } - return root.ID, resp, nil -} - -// Get an existing droplet autoscale pool -func (d *DropletAutoscaleServiceOp) Get(ctx context.Context, id string) (*DropletAutoscalePool, *Response, error) { - req, err := d.client.NewRequest(ctx, http.MethodGet, fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, id), nil) - if err != nil { - return nil, nil, err - } - root := new(DropletAutoscalePool) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return nil, nil, err - } - return root, resp, err -} - -// List all existing droplet autoscale pools -func (d *DropletAutoscaleServiceOp) List(ctx context.Context, opts *ListOptions) ([]*DropletAutoscalePool, *Response, error) { - path, err := addOptions(dropletAutoscaleBasePath, opts) - if err != nil { - return nil, nil, err - } - req, err := d.client.NewRequest(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, nil, err - } - root := new(dropletAutoscalePoolsRoot) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return nil, nil, err - } - if root.Links != nil { - resp.Links = root.Links - } - if root.Meta != nil { - resp.Meta = root.Meta - } - return root.AutoscalePools, resp, err -} - -// ListMembers all members for an existing droplet autoscale pool -func (d *DropletAutoscaleServiceOp) ListMembers(ctx context.Context, id string, opts *ListOptions) ([]*DropletAutoscaleResource, *Response, error) { - path, err := addOptions(fmt.Sprintf("%s/%s/members", dropletAutoscaleBasePath, id), opts) - if err != nil { - return nil, nil, err - } - req, err := d.client.NewRequest(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, nil, err - } - root := new(dropletAutoscaleMembersRoot) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return nil, nil, err - } - if root.Links != nil { - resp.Links = root.Links - } - if root.Meta != nil { - resp.Meta = root.Meta - } - return root.Droplets, resp, err -} - -// ListHistory all history events for an existing droplet autoscale pool -func (d *DropletAutoscaleServiceOp) ListHistory(ctx context.Context, id string, opts *ListOptions) ([]*DropletAutoscaleHistoryEvent, *Response, error) { - path, err := addOptions(fmt.Sprintf("%s/%s/history", dropletAutoscaleBasePath, id), opts) - if err != nil { - return nil, nil, err - } - req, err := d.client.NewRequest(ctx, http.MethodGet, path, nil) - if err != nil { - return nil, nil, err - } - root := new(dropletAutoscaleHistoryEventsRoot) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return nil, nil, err - } - if root.Links != nil { - resp.Links = root.Links - } - if root.Meta != nil { - resp.Meta = root.Meta - } - return root.History, resp, err -} - -// Update an existing autoscale pool -func (d *DropletAutoscaleServiceOp) Update(ctx context.Context, id string, updateReq *DropletAutoscalePoolRequest) (string, *Response, error) { - req, err := d.client.NewRequest(ctx, http.MethodPut, fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, id), updateReq) - if err != nil { - return "", nil, err - } - root := new(dropletAutoscalePoolRoot) - resp, err := d.client.Do(ctx, req, root) - if err != nil { - return "", nil, err - } - return root.ID, resp, nil -} - -// Delete an existing autoscale pool -func (d *DropletAutoscaleServiceOp) Delete(ctx context.Context, id string) (*Response, error) { - req, err := d.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, id), nil) - if err != nil { - return nil, err - } - return d.client.Do(ctx, req, nil) -} - -// DeleteDangerous deletes an existing autoscale pool with all underlying resources -func (d *DropletAutoscaleServiceOp) DeleteDangerous(ctx context.Context, id string) (*Response, error) { - req, err := d.client.NewRequest(ctx, http.MethodDelete, fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, id), nil) - req.Header.Set("X-Dangerous", "true") - if err != nil { - return nil, err - } - return d.client.Do(ctx, req, nil) -} diff --git a/droplet_autoscaler_test.go b/droplet_autoscaler_test.go deleted file mode 100644 index 9ef6b6a8..00000000 --- a/droplet_autoscaler_test.go +++ /dev/null @@ -1,565 +0,0 @@ -package godo - -import ( - "encoding/json" - "fmt" - "net/http" - "sort" - "strconv" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -var dropletAutoscaleListHistoryJSONResponse = ` -{ - "history": [ - { - "history_event_id": "4344c45f-7574-493b-a96c-df805c65a900", - "current_instance_count": 0, - "desired_instance_count": 1, - "reason": "configuration update", - "status": "success", - "created_at": "2024-10-18T19:03:09Z", - "updated_at": "2024-10-18T19:03:09Z" - }, - { - "history_event_id": "9ad436f7-af57-49ff-b416-0043721055b2", - "current_instance_count": 1, - "desired_instance_count": 2, - "reason": "scaling up (desired=2 current=1)", - "status": "success", - "created_at": "2024-10-18T19:15:24Z", - "updated_at": "2024-10-18T19:15:24Z" - }, - { - "history_event_id": "45390191-d077-49e9-a3c4-c2eb903bc1a2", - "current_instance_count": 2, - "desired_instance_count": 1, - "reason": "scaling down (desired=1 current=2)", - "status": "success", - "created_at": "2024-10-18T19:47:24Z", - "updated_at": "2024-10-18T19:47:24Z" - } - ], - "links": {}, - "meta": { - "total": 3 - } -} -` - -var dropletAutoscaleListMembersJSONResponse = ` -{ - "droplets": [ - { - "droplet_id": 1677149, - "created_at": "2024-10-18T19:03:09Z", - "updated_at": "2024-10-18T19:03:24Z", - "health_status": "healthy", - "status": "active", - "current_utilization": { - "memory": 0.35, - "cpu": 0.0012 - } - }, - { - "droplet_id": 1677150, - "created_at": "2024-10-18T19:04:09Z", - "updated_at": "2024-10-18T19:04:24Z", - "health_status": "healthy", - "status": "active", - "current_utilization": { - "memory": 0.40, - "cpu": 0.0013 - } - } - ], - "links": {}, - "meta": { - "total": 2 - } -} -` - -var dropletAutoscaleListJSONResponse = ` -{ - "autoscale_pools": [ - { - "id": "a4456a02-133d-4fea-8f2d-94dc6a7bf9c9", - "name": "test-autoscalergroup-03", - "config": { - "min_instances": 1, - "max_instances": 5, - "target_cpu_utilization": 0.5, - "cooldown_minutes": 5 - }, - "droplet_template": { - "size": "s-1vcpu-512mb-10gb", - "region": "s2r1", - "image": "547864", - "tags": [ - "test-ag-01" - ], - "ssh_keys": [ - "372862", - "367582", - "355790" - ], - "vpc_uuid": "72b0812c-7535-4388-8507-5ad29b4487b3", - "with_droplet_agent": false, - "project_id": "", - "ipv6": true, - "user_data": "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n" - }, - "created_at": "2024-10-21T13:05:23Z", - "updated_at": "2024-10-21T13:05:23Z", - "current_utilization": { - "memory": 0.33, - "cpu": 0.0007 - }, - "status": "active" - }, - { - "id": "1044bfca-e490-44a1-aa1c-6f002daf6a13", - "name": "test-autoscalergroup-01", - "config": { - "min_instances": 1, - "max_instances": 5, - "target_cpu_utilization": 0.5, - "cooldown_minutes": 5 - }, - "droplet_template": { - "size": "s-1vcpu-512mb-10gb", - "region": "s2r1", - "image": "547864", - "tags": [ - "test-ag-01" - ], - "ssh_keys": [ - "372862", - "367582", - "355790" - ], - "vpc_uuid": "72b0812c-7535-4388-8507-5ad29b4487b3", - "with_droplet_agent": false, - "project_id": "", - "ipv6": true, - "user_data": "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n" - }, - "created_at": "2024-10-18T19:03:08Z", - "updated_at": "2024-10-18T19:03:08Z", - "current_utilization": { - "memory": 0.35, - "cpu": 0.0009 - }, - "status": "active" - }, - { - "id": "b92962b5-26a5-4e63-a1d9-a0f5d44b4f23", - "name": "test-autoscalergroup-02", - "config": { - "min_instances": 1, - "max_instances": 5, - "target_cpu_utilization": 0.5, - "cooldown_minutes": 5 - }, - "droplet_template": { - "size": "s-1vcpu-512mb-10gb", - "region": "s2r1", - "image": "547864", - "tags": [ - "test-ag-01" - ], - "ssh_keys": [ - "372862", - "367582", - "355790" - ], - "vpc_uuid": "72b0812c-7535-4388-8507-5ad29b4487b3", - "with_droplet_agent": false, - "project_id": "", - "ipv6": true, - "user_data": "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n" - }, - "created_at": "2024-10-21T13:05:12Z", - "updated_at": "2024-10-21T13:05:12Z", - "current_utilization": { - "memory": 0.56, - "cpu": 0.0002 - }, - "status": "active" - } - ], - "links": {}, - "meta": { - "total": 3 - } -} -` - -var dropletAutoscaleGetJSONResponse = ` -{ - "id": "1044bfca-e490-44a1-aa1c-6f002daf6a13", - "name": "test-autoscalergroup-01", - "config": { - "min_instances": 1, - "max_instances": 5, - "target_cpu_utilization": 0.5, - "cooldown_minutes": 5 - }, - "droplet_template": { - "size": "s-1vcpu-512mb-10gb", - "region": "s2r1", - "image": "547864", - "tags": [ - "test-ag-01" - ], - "ssh_keys": [ - "372862", - "367582", - "355790" - ], - "vpc_uuid": "72b0812c-7535-4388-8507-5ad29b4487b3", - "with_droplet_agent": false, - "project_id": "", - "ipv6": true, - "user_data": "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n" - }, - "created_at": "2024-10-18T19:03:08Z", - "updated_at": "2024-10-18T19:03:08Z", - "current_utilization": { - "memory": 0.35, - "cpu": 0.0008 - }, - "status": "active" -} -` - -func TestDropletAutoscaler_Get(t *testing.T) { - setup() - defer teardown() - - autoscalePoolID := "1044bfca-e490-44a1-aa1c-6f002daf6a13" - mux.HandleFunc(fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprintf(w, dropletAutoscaleGetJSONResponse) - }) - - expectedPoolResp := &DropletAutoscalePool{ - ID: "1044bfca-e490-44a1-aa1c-6f002daf6a13", - Name: "test-autoscalergroup-01", - Config: &DropletAutoscaleConfiguration{ - MinInstances: 1, - MaxInstances: 5, - TargetCPUUtilization: 0.5, - CooldownMinutes: 5, - }, - DropletTemplate: &DropletAutoscaleResourceTemplate{ - Size: "s-1vcpu-512mb-10gb", - Region: "s2r1", - Image: "547864", - Tags: []string{"test-ag-01"}, - SSHKeys: []string{"372862", "367582", "355790"}, - VpcUUID: "72b0812c-7535-4388-8507-5ad29b4487b3", - IPV6: true, - UserData: "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n", - }, - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.35, - CPU: 0.0008, - }, - Status: "active", - } - - gotPoolResp, _, err := client.DropletAutoscale.Get(ctx, autoscalePoolID) - require.NoError(t, err) - require.NotNil(t, gotPoolResp) - expectedPoolResp.CreatedAt = gotPoolResp.CreatedAt - expectedPoolResp.UpdatedAt = gotPoolResp.UpdatedAt - assert.Equal(t, expectedPoolResp, gotPoolResp) -} - -func TestDropletAutoscaler_List(t *testing.T) { - setup() - defer teardown() - - mux.HandleFunc(dropletAutoscaleBasePath, func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprintf(w, dropletAutoscaleListJSONResponse) - }) - - expectedConfig := &DropletAutoscaleConfiguration{ - MinInstances: 1, - MaxInstances: 5, - TargetCPUUtilization: 0.5, - CooldownMinutes: 5, - } - expectedDropletTemplate := &DropletAutoscaleResourceTemplate{ - Size: "s-1vcpu-512mb-10gb", - Region: "s2r1", - Image: "547864", - Tags: []string{"test-ag-01"}, - SSHKeys: []string{"372862", "367582", "355790"}, - VpcUUID: "72b0812c-7535-4388-8507-5ad29b4487b3", - IPV6: true, - UserData: "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n", - } - expectedPoolsResp := []*DropletAutoscalePool{ - { - ID: "1044bfca-e490-44a1-aa1c-6f002daf6a13", - Name: "test-autoscalergroup-01", - Config: expectedConfig, - DropletTemplate: expectedDropletTemplate, - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.35, - CPU: 0.0009, - }, - Status: "active", - }, - { - ID: "b92962b5-26a5-4e63-a1d9-a0f5d44b4f23", - Name: "test-autoscalergroup-02", - Config: expectedConfig, - DropletTemplate: expectedDropletTemplate, - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.56, - CPU: 0.0002, - }, - Status: "active", - }, - { - ID: "a4456a02-133d-4fea-8f2d-94dc6a7bf9c9", - Name: "test-autoscalergroup-03", - Config: expectedConfig, - DropletTemplate: expectedDropletTemplate, - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.33, - CPU: 0.0007, - }, - Status: "active", - }, - } - - gotPoolsResp, _, err := client.DropletAutoscale.List(ctx, nil) - require.NoError(t, err) - require.NotEmpty(t, gotPoolsResp) - sort.SliceStable(gotPoolsResp, func(i, j int) bool { - return gotPoolsResp[i].Name < gotPoolsResp[j].Name - }) - for idx := range gotPoolsResp { - expectedPoolsResp[idx].CreatedAt = gotPoolsResp[idx].CreatedAt - expectedPoolsResp[idx].UpdatedAt = gotPoolsResp[idx].UpdatedAt - } - assert.Equal(t, expectedPoolsResp, gotPoolsResp) -} - -func TestDropletAutoscaler_ListMembers(t *testing.T) { - setup() - defer teardown() - - autoscalePoolID := "1044bfca-e490-44a1-aa1c-6f002daf6a13" - mux.HandleFunc(fmt.Sprintf("%s/%s/members", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprintf(w, dropletAutoscaleListMembersJSONResponse) - }) - - expectedMembersResp := []*DropletAutoscaleResource{ - { - DropletID: 1677149, - HealthStatus: "healthy", - Status: "active", - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.35, - CPU: 0.0012, - }, - }, - { - DropletID: 1677150, - HealthStatus: "healthy", - Status: "active", - CurrentUtilization: &DropletAutoscaleResourceUtilization{ - Memory: 0.40, - CPU: 0.0013, - }, - }, - } - - gotMembersResp, _, err := client.DropletAutoscale.ListMembers(ctx, autoscalePoolID, nil) - require.NoError(t, err) - require.NotEmpty(t, gotMembersResp) - sort.SliceStable(gotMembersResp, func(i, j int) bool { - return gotMembersResp[i].DropletID < gotMembersResp[j].DropletID - }) - for idx := range gotMembersResp { - expectedMembersResp[idx].CreatedAt = gotMembersResp[idx].CreatedAt - expectedMembersResp[idx].UpdatedAt = gotMembersResp[idx].UpdatedAt - } - assert.Equal(t, expectedMembersResp, gotMembersResp) -} - -func TestDropletAutoscaler_ListHistory(t *testing.T) { - setup() - defer teardown() - - autoscalePoolID := "1044bfca-e490-44a1-aa1c-6f002daf6a13" - mux.HandleFunc(fmt.Sprintf("%s/%s/history", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodGet) - fmt.Fprintf(w, dropletAutoscaleListHistoryJSONResponse) - }) - - expectedHistoryResp := []*DropletAutoscaleHistoryEvent{ - { - HistoryEventID: "4344c45f-7574-493b-a96c-df805c65a900", - CurrentInstanceCount: 0, - DesiredInstanceCount: 1, - Reason: "configuration update", - Status: "success", - }, - { - HistoryEventID: "9ad436f7-af57-49ff-b416-0043721055b2", - CurrentInstanceCount: 1, - DesiredInstanceCount: 2, - Reason: "scaling up (desired=2 current=1)", - Status: "success", - }, - { - HistoryEventID: "45390191-d077-49e9-a3c4-c2eb903bc1a2", - CurrentInstanceCount: 2, - DesiredInstanceCount: 1, - Reason: "scaling down (desired=1 current=2)", - Status: "success", - }, - } - - gotHistoryResp, _, err := client.DropletAutoscale.ListHistory(ctx, autoscalePoolID, nil) - require.NoError(t, err) - require.NotEmpty(t, gotHistoryResp) - sort.SliceStable(gotHistoryResp, func(i, j int) bool { - return gotHistoryResp[i].CreatedAt.Before(gotHistoryResp[j].CreatedAt) - }) - for idx := range gotHistoryResp { - expectedHistoryResp[idx].CreatedAt = gotHistoryResp[idx].CreatedAt - expectedHistoryResp[idx].UpdatedAt = gotHistoryResp[idx].UpdatedAt - } - assert.Equal(t, expectedHistoryResp, gotHistoryResp) -} - -func TestDropletAutoscaler_Create(t *testing.T) { - setup() - defer teardown() - - createReq := &DropletAutoscalePoolRequest{ - Name: "test-autoscalergroup-01", - Config: &DropletAutoscaleConfiguration{ - MinInstances: 1, - MaxInstances: 5, - TargetCPUUtilization: 0.5, - }, - DropletTemplate: &DropletAutoscaleResourceTemplate{ - Size: "s-1vcpu-512mb-10gb", - Region: "s2r1", - Image: "547864", - Tags: []string{"test-ag-01"}, - SSHKeys: []string{"372862", "367582", "355790"}, - VpcUUID: "72b0812c-7535-4388-8507-5ad29b4487b3", - IPV6: true, - UserData: "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n", - }, - } - - mux.HandleFunc(dropletAutoscaleBasePath, func(w http.ResponseWriter, r *http.Request) { - req := new(DropletAutoscalePoolRequest) - err := json.NewDecoder(r.Body).Decode(req) - if err != nil { - t.Fatal(err) - } - testMethod(t, r, http.MethodPost) - assert.Equal(t, createReq, req) - fmt.Fprintf(w, ` -{ - "id": "d50d8276-ad17-475d-8d2a-26b0acac756c" -}`) - }) - - createPoolResp, _, err := client.DropletAutoscale.Create(ctx, createReq) - require.NoError(t, err) - require.NotEmpty(t, createPoolResp) - assert.Equal(t, "d50d8276-ad17-475d-8d2a-26b0acac756c", createPoolResp) -} - -func TestDropletAutoscaler_Update(t *testing.T) { - setup() - defer teardown() - - updateReq := &DropletAutoscalePoolRequest{ - Name: "test-autoscalergroup-01", - Config: &DropletAutoscaleConfiguration{ - MinInstances: 1, - MaxInstances: 5, - TargetCPUUtilization: 0.5, - }, - DropletTemplate: &DropletAutoscaleResourceTemplate{ - Size: "s-1vcpu-512mb-10gb", - Region: "s2r1", - Image: "547864", - Tags: []string{"test-ag-01"}, - SSHKeys: []string{"372862", "367582", "355790"}, - VpcUUID: "72b0812c-7535-4388-8507-5ad29b4487b3", - IPV6: true, - UserData: "\n#cloud-config\nruncmd:\n- apt-get update\n- apt-get install -y stress-ng\n", - }, - } - - autoscalePoolID := "d50d8276-ad17-475d-8d2a-26b0acac756c" - mux.HandleFunc(fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - req := new(DropletAutoscalePoolRequest) - err := json.NewDecoder(r.Body).Decode(req) - if err != nil { - t.Fatal(err) - } - testMethod(t, r, http.MethodPut) - assert.Equal(t, updateReq, req) - fmt.Fprintf(w, ` -{ - "id": "d50d8276-ad17-475d-8d2a-26b0acac756c" -}`) - }) - - updatePoolResp, _, err := client.DropletAutoscale.Update(ctx, autoscalePoolID, updateReq) - require.NoError(t, err) - require.NotEmpty(t, updatePoolResp) - assert.Equal(t, autoscalePoolID, updatePoolResp) -} - -func TestDropletAutoscaler_Delete(t *testing.T) { - setup() - defer teardown() - - autoscalePoolID := "d50d8276-ad17-475d-8d2a-26b0acac756c" - mux.HandleFunc(fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodDelete) - }) - - _, err := client.DropletAutoscale.Delete(ctx, autoscalePoolID) - assert.NoError(t, err) -} - -func TestDropletAutoscaler_DeleteDangerous(t *testing.T) { - setup() - defer teardown() - - autoscalePoolID := "d50d8276-ad17-475d-8d2a-26b0acac756c" - mux.HandleFunc(fmt.Sprintf("%s/%s", dropletAutoscaleBasePath, autoscalePoolID), func(w http.ResponseWriter, r *http.Request) { - testMethod(t, r, http.MethodDelete) - if expectedHeader, err := strconv.ParseBool(r.Header.Get("X-Dangerous")); err != nil { - t.Fatal(err) - } else if !expectedHeader { - t.Errorf("Request header = %v, expected %v", r.Header.Get("X-Dangerous"), true) - } - }) - - _, err := client.DropletAutoscale.DeleteDangerous(ctx, autoscalePoolID) - assert.NoError(t, err) -}