From d95eff8590474f1ba1c2f08e0f8f79b01114652f Mon Sep 17 00:00:00 2001 From: Lee Spottiswood Date: Mon, 16 May 2022 15:50:23 +0100 Subject: [PATCH] add support for retrieving NIC IP addresses (#115) --- pkg/service/ecloud/service.go | 2 + pkg/service/ecloud/service_nic.go | 49 ++++++++++++++- pkg/service/ecloud/service_nic_test.go | 85 +++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 2 deletions(-) diff --git a/pkg/service/ecloud/service.go b/pkg/service/ecloud/service.go index 6c91d15..02d5fb6 100644 --- a/pkg/service/ecloud/service.go +++ b/pkg/service/ecloud/service.go @@ -258,6 +258,8 @@ type ECloudService interface { GetNIC(nicID string) (NIC, error) GetNICTasks(nicID string, parameters connection.APIRequestParameters) ([]Task, error) GetNICTasksPaginated(nicID string, parameters connection.APIRequestParameters) (*PaginatedTask, error) + GetNICIPAddresses(nicID string, parameters connection.APIRequestParameters) ([]IPAddress, error) + GetNICIPAddressesPaginated(nicID string, parameters connection.APIRequestParameters) (*PaginatedIPAddress, error) AssignNICIPAddress(nicID string, req AssignIPAddressRequest) (string, error) UnassignNICIPAddress(nicID string, ipID string) (string, error) diff --git a/pkg/service/ecloud/service_nic.go b/pkg/service/ecloud/service_nic.go index f6c1f37..06e43f0 100644 --- a/pkg/service/ecloud/service_nic.go +++ b/pkg/service/ecloud/service_nic.go @@ -118,6 +118,53 @@ func (s *Service) getNICTasksPaginatedResponseBody(nicID string, parameters conn }) } +// GetNICIPAddress retrieves a list of NIC IP addresses +func (s *Service) GetNICIPAddresses(nicID string, parameters connection.APIRequestParameters) ([]IPAddress, error) { + var ips []IPAddress + + getFunc := func(p connection.APIRequestParameters) (connection.Paginated, error) { + return s.GetNICIPAddressesPaginated(nicID, p) + } + + responseFunc := func(response connection.Paginated) { + for _, ip := range response.(*PaginatedIPAddress).Items { + ips = append(ips, ip) + } + } + + return ips, connection.InvokeRequestAll(getFunc, responseFunc, parameters) +} + +// GetNICIPAddressPaginated retrieves a paginated list of NIC IP addresses +func (s *Service) GetNICIPAddressesPaginated(nicID string, parameters connection.APIRequestParameters) (*PaginatedIPAddress, error) { + body, err := s.getNICIPAddressesPaginatedResponseBody(nicID, parameters) + + return NewPaginatedIPAddress(func(p connection.APIRequestParameters) (connection.Paginated, error) { + return s.GetNICIPAddressesPaginated(nicID, p) + }, parameters, body.Metadata.Pagination, body.Data), err +} + +func (s *Service) getNICIPAddressesPaginatedResponseBody(nicID string, parameters connection.APIRequestParameters) (*GetIPAddressSliceResponseBody, error) { + body := &GetIPAddressSliceResponseBody{} + + if nicID == "" { + return body, fmt.Errorf("invalid nic id") + } + + response, err := s.connection.Get(fmt.Sprintf("/ecloud/v2/nics/%s/ip-addresses", nicID), parameters) + if err != nil { + return body, err + } + + return body, response.HandleResponse(body, func(resp *connection.APIResponse) error { + if response.StatusCode == 404 { + return &NICNotFoundError{ID: nicID} + } + + return nil + }) +} + func (s *Service) AssignNICIPAddress(nicID string, req AssignIPAddressRequest) (string, error) { body, err := s.assignNICIPAddressResponseBody(nicID, req) @@ -175,4 +222,4 @@ func (s *Service) unassignNICIPAddressResponseBody(nicID string, ipID string) (* return nil }) -} \ No newline at end of file +} diff --git a/pkg/service/ecloud/service_nic_test.go b/pkg/service/ecloud/service_nic_test.go index 18e6b92..7a255df 100644 --- a/pkg/service/ecloud/service_nic_test.go +++ b/pkg/service/ecloud/service_nic_test.go @@ -222,6 +222,89 @@ func TestGetNICTasks(t *testing.T) { }) } +func TestGetNICIPAddresses(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/nics/nic-abcdef12/ip-addresses", gomock.Any()).Return(&connection.APIResponse{ + Response: &http.Response{ + Body: ioutil.NopCloser(bytes.NewReader([]byte("{\"data\":[{\"id\":\"ip-abcdef12\"}],\"meta\":{\"pagination\":{\"total_pages\":1}}}"))), + StatusCode: 200, + }, + }, nil).Times(1) + + ips, err := s.GetNICIPAddresses("nic-abcdef12", connection.APIRequestParameters{}) + + assert.Nil(t, err) + assert.Len(t, ips, 1) + assert.Equal(t, "ip-abcdef12", ips[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/nics/nic-abcdef12/ip-addresses", gomock.Any()).Return(&connection.APIResponse{}, errors.New("test error 1")) + + _, err := s.GetNICIPAddresses("nic-abcdef12", connection.APIRequestParameters{}) + + assert.NotNil(t, err) + assert.Equal(t, "test error 1", err.Error()) + }) + + t.Run("InvalidNICID_ReturnsError", func(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + c := mocks.NewMockConnection(mockCtrl) + + s := Service{ + connection: c, + } + + _, err := s.GetNICIPAddresses("", connection.APIRequestParameters{}) + + assert.NotNil(t, err) + assert.Equal(t, "invalid nic id", err.Error()) + }) + + t.Run("404_ReturnsRouterNotFoundError", func(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + c := mocks.NewMockConnection(mockCtrl) + + s := Service{ + connection: c, + } + + c.EXPECT().Get("/ecloud/v2/nics/nic-abcdef12/ip-addresses", gomock.Any()).Return(&connection.APIResponse{ + Response: &http.Response{ + Body: ioutil.NopCloser(bytes.NewReader([]byte(""))), + StatusCode: 404, + }, + }, nil).Times(1) + + _, err := s.GetNICIPAddresses("nic-abcdef12", connection.APIRequestParameters{}) + + assert.NotNil(t, err) + assert.IsType(t, &NICNotFoundError{}, err) + }) +} + func TestAssignNICIPAddress(t *testing.T) { t.Run("Valid", func(t *testing.T) { mockCtrl := gomock.NewController(t) @@ -404,4 +487,4 @@ func TestUnassignNICIPAddress(t *testing.T) { assert.NotNil(t, err) assert.IsType(t, &NICNotFoundError{}, err) }) -} \ No newline at end of file +}