Skip to content

Commit

Permalink
Adds eCloud guest execution script functionality (#153)
Browse files Browse the repository at this point in the history
Co-authored-by: Patrick Clough <[email protected]>
  • Loading branch information
PCloughster and PCloughster authored Jul 29, 2024
1 parent 025fb39 commit f6337c7
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 0 deletions.
6 changes: 6 additions & 0 deletions pkg/service/ecloud/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -630,3 +630,9 @@ type PatchNATOverloadRuleRequest struct {
Subnet string `json:"subnet,omitempty"`
Action NATOverloadRuleAction `json:"action,omitempty"`
}

type ExecuteInstanceScriptRequest struct {
Script string `json:"script"`
Username string `json:"username"`
Password string `json:"password"`
}
1 change: 1 addition & 0 deletions pkg/service/ecloud/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ type ECloudService interface {
CreateInstanceImage(instanceID string, req CreateInstanceImageRequest) (TaskReference, error)
EncryptInstance(instanceID string) (string, error)
DecryptInstance(instanceID string) (string, error)
ExecuteInstanceScript(instanceID string, req ExecuteInstanceScriptRequest) (string, error)

// Floating IP
GetFloatingIPs(parameters connection.APIRequestParameters) ([]FloatingIP, error)
Expand Down
14 changes: 14 additions & 0 deletions pkg/service/ecloud/service_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,3 +667,17 @@ func (s *Service) decryptInstanceResponseBody(instanceID string) (*connection.AP

return connection.Put[TaskReference](s.connection, fmt.Sprintf("/ecloud/v2/instances/%s/decrypt", instanceID), nil, connection.NotFoundResponseHandler(&InstanceNotFoundError{ID: instanceID}))
}

func (s *Service) ExecuteInstanceScript(instanceID string, req ExecuteInstanceScriptRequest) (string, error) {
body, err := s.executeInstanceScriptResponseBody(instanceID, req)

return body.Data.TaskID, err
}

func (s *Service) executeInstanceScriptResponseBody(instanceID string, req ExecuteInstanceScriptRequest) (*connection.APIResponseBodyData[TaskReference], error) {
if instanceID == "" {
return &connection.APIResponseBodyData[TaskReference]{}, fmt.Errorf("invalid instance id")
}

return connection.Post[TaskReference](s.connection, fmt.Sprintf("/ecloud/v2/instances/%s/user-script", instanceID), &req, connection.NotFoundResponseHandler(&InstanceNotFoundError{ID: instanceID}))
}
78 changes: 78 additions & 0 deletions pkg/service/ecloud/service_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ecloud
import (
"bytes"
"errors"
"io"
"io/ioutil"
"net/http"
"testing"
Expand Down Expand Up @@ -1890,3 +1891,80 @@ func TestDecryptInstance(t *testing.T) {
assert.Equal(t, "invalid instance id", err.Error())
})
}

func TestExecuteInstanceScript(t *testing.T) {
t.Run("Valid_NoError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

c := mocks.NewMockConnection(mockCtrl)

s := Service{
connection: c,
}

c.EXPECT().Post("/ecloud/v2/instances/i-abcdef12/user-script", gomock.Any()).Return(&connection.APIResponse{
Response: &http.Response{
Body: io.NopCloser(bytes.NewReader([]byte("{\"data\":{\"task_id\":\"task-abcdef12\"},\"meta\":{\"location\":\"\"}}"))),
StatusCode: 202,
},
}, nil)

executeRequest := ExecuteInstanceScriptRequest{
Script: "test script 1",
Username: "test_user",
Password: "test_password",
}

taskID, err := s.ExecuteInstanceScript("i-abcdef12", executeRequest)

assert.Nil(t, err)
assert.Equal(t, "task-abcdef12", taskID)
})

t.Run("ConnectionError_ReturnsError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

c := mocks.NewMockConnection(mockCtrl)

s := Service{
connection: c,
}

c.EXPECT().Post("/ecloud/v2/instances/i-abcdef12/user-script", gomock.Any()).Return(&connection.APIResponse{}, errors.New("test error 1")).Times(1)

executeRequest := ExecuteInstanceScriptRequest{
Script: "test script 1",
Username: "test_user",
Password: "test_password",
}

_, err := s.ExecuteInstanceScript("i-abcdef12", executeRequest)

assert.NotNil(t, err)
assert.Equal(t, "test error 1", err.Error())
})

t.Run("InvalidInstanceID_ReturnsError", func(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

c := mocks.NewMockConnection(mockCtrl)

s := Service{
connection: c,
}

executeRequest := ExecuteInstanceScriptRequest{
Script: "test script 1",
Username: "test_user",
Password: "test_password",
}

_, err := s.ExecuteInstanceScript("", executeRequest)

assert.NotNil(t, err)
assert.Equal(t, "invalid instance id", err.Error())
})
}

0 comments on commit f6337c7

Please sign in to comment.