Skip to content

Commit

Permalink
add method for retrieving floating IPs indirectly associated with ins…
Browse files Browse the repository at this point in the history
…tances (#99)
  • Loading branch information
0x4c6565 committed Oct 18, 2021
1 parent d85b3fc commit c4a7185
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pkg/service/ecloud/service.go
Expand Up @@ -173,6 +173,8 @@ type ECloudService interface {
GetInstanceTasksPaginated(instanceID string, parameters connection.APIRequestParameters) (*PaginatedTask, error)
AttachInstanceVolume(instanceID string, req AttachDetachInstanceVolumeRequest) (string, error)
DetachInstanceVolume(instanceID string, req AttachDetachInstanceVolumeRequest) (string, error)
GetInstanceFloatingIPs(instanceID string, parameters connection.APIRequestParameters) ([]FloatingIP, error)
GetInstanceFloatingIPsPaginated(instanceID string, parameters connection.APIRequestParameters) (*PaginatedFloatingIP, error)

// Floating IP
GetFloatingIPs(parameters connection.APIRequestParameters) ([]FloatingIP, error)
Expand Down
47 changes: 47 additions & 0 deletions pkg/service/ecloud/service_instance.go
Expand Up @@ -640,3 +640,50 @@ func (s *Service) detachInstanceVolumeResponseBody(instanceID string, req Attach
return nil
})
}

// GetInstanceFloatingIPs retrieves a list of instance fips
func (s *Service) GetInstanceFloatingIPs(instanceID string, parameters connection.APIRequestParameters) ([]FloatingIP, error) {
var fips []FloatingIP

return fips, connection.InvokeRequestAll(
func(p connection.APIRequestParameters) (connection.Paginated, error) {
return s.GetInstanceFloatingIPsPaginated(instanceID, p)
},
func(response connection.Paginated) {
for _, fip := range response.(*PaginatedFloatingIP).Items {
fips = append(fips, fip)
}
},
parameters,
)
}

// GetInstanceFloatingIPsPaginated retrieves a paginated list of instance floating IPs
func (s *Service) GetInstanceFloatingIPsPaginated(instanceID string, parameters connection.APIRequestParameters) (*PaginatedFloatingIP, error) {
body, err := s.getInstanceFloatingIPsPaginatedResponseBody(instanceID, parameters)

return NewPaginatedFloatingIP(func(p connection.APIRequestParameters) (connection.Paginated, error) {
return s.GetInstanceFloatingIPsPaginated(instanceID, p)
}, parameters, body.Metadata.Pagination, body.Data), err
}

func (s *Service) getInstanceFloatingIPsPaginatedResponseBody(instanceID string, parameters connection.APIRequestParameters) (*GetFloatingIPSliceResponseBody, error) {
body := &GetFloatingIPSliceResponseBody{}

if instanceID == "" {
return body, fmt.Errorf("invalid instance id")
}

response, err := s.connection.Get(fmt.Sprintf("/ecloud/v2/instances/%s/floating-ips", instanceID), parameters)
if err != nil {
return body, err
}

return body, response.HandleResponse(body, func(resp *connection.APIResponse) error {
if response.StatusCode == 404 {
return &InstanceNotFoundError{ID: instanceID}
}

return nil
})
}
83 changes: 83 additions & 0 deletions pkg/service/ecloud/service_instance_test.go
Expand Up @@ -1599,3 +1599,86 @@ func TestDetachInstanceVolume(t *testing.T) {
assert.IsType(t, &InstanceNotFoundError{}, err)
})
}

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

c := mocks.NewMockConnection(mockCtrl)

s := Service{
connection: c,
}

c.EXPECT().Get("/ecloud/v2/instances/i-abcdef12/floating-ips", gomock.Any()).Return(&connection.APIResponse{
Response: &http.Response{
Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"data\":[{\"id\":\"vol-abcdef12\"}],\"meta\":{\"pagination\":{\"total_pages\":1}}}"))),
StatusCode: 200,
},
}, nil)

instances, err := s.GetInstanceFloatingIPs("i-abcdef12", connection.APIRequestParameters{})

assert.Nil(t, err)
assert.Len(t, instances, 1)
assert.Equal(t, "vol-abcdef12", instances[0].ID)
})

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().Get("/ecloud/v2/instances/i-abcdef12/floating-ips", gomock.Any()).Return(&connection.APIResponse{}, errors.New("test error 1"))

_, err := s.GetInstanceFloatingIPs("i-abcdef12", connection.APIRequestParameters{})

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,
}

_, err := s.GetInstanceFloatingIPs("", connection.APIRequestParameters{})

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

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

c := mocks.NewMockConnection(mockCtrl)

s := Service{
connection: c,
}

c.EXPECT().Get("/ecloud/v2/instances/i-abcdef12/floating-ips", gomock.Any()).Return(&connection.APIResponse{
Response: &http.Response{
Body: ioutil.NopCloser(bytes.NewReader([]byte(""))),
StatusCode: 404,
},
}, nil)

_, err := s.GetInstanceFloatingIPs("i-abcdef12", connection.APIRequestParameters{})

assert.NotNil(t, err)
assert.IsType(t, &InstanceNotFoundError{}, err)
})
}

0 comments on commit c4a7185

Please sign in to comment.