diff --git a/pkg/service/ecloud/request.go b/pkg/service/ecloud/request.go index f0bb987..5faf768 100644 --- a/pkg/service/ecloud/request.go +++ b/pkg/service/ecloud/request.go @@ -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"` +} diff --git a/pkg/service/ecloud/service.go b/pkg/service/ecloud/service.go index 84b1f3c..38ec607 100644 --- a/pkg/service/ecloud/service.go +++ b/pkg/service/ecloud/service.go @@ -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) diff --git a/pkg/service/ecloud/service_instance.go b/pkg/service/ecloud/service_instance.go index 278b1ee..779f6a3 100644 --- a/pkg/service/ecloud/service_instance.go +++ b/pkg/service/ecloud/service_instance.go @@ -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})) +} diff --git a/pkg/service/ecloud/service_instance_test.go b/pkg/service/ecloud/service_instance_test.go index 946adcb..e4ed9ac 100644 --- a/pkg/service/ecloud/service_instance_test.go +++ b/pkg/service/ecloud/service_instance_test.go @@ -3,6 +3,7 @@ package ecloud import ( "bytes" "errors" + "io" "io/ioutil" "net/http" "testing" @@ -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()) + }) +}