From 9a2ad81157630365aea0a2ccbe69168c489c6f00 Mon Sep 17 00:00:00 2001 From: Alex Goryev Date: Mon, 11 Mar 2024 16:38:35 +0300 Subject: [PATCH] Add floating IPs create and delete endpoints --- floating_ips.go | 56 ++++++++++++++++++++++++++++++++ floating_ips_test.go | 76 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 floating_ips.go create mode 100644 floating_ips_test.go diff --git a/floating_ips.go b/floating_ips.go new file mode 100644 index 0000000..fde149e --- /dev/null +++ b/floating_ips.go @@ -0,0 +1,56 @@ +package dbaas + +import ( + "context" + "encoding/json" + "fmt" + "net/http" +) + +// FloatingIPsOpts represents create|delete options for creating|deleting +// Floating IP in|from existed cluster. +type FloatingIPsOpts struct { + InstanceID string `json:"instance_id"` +} + +const FloatingIPsURI = "/floating-ips" + +// CreateFloatingIP creates FloatingIP for provided instance of an existing datastore. +func (api *API) CreateFloatingIP(ctx context.Context, opts FloatingIPsOpts) error { + floatingIPsOpts := struct { + FloatingIP FloatingIPsOpts `json:"floating-ip"` + }{ + FloatingIP: opts, + } + requestBody, err := json.Marshal(floatingIPsOpts) + if err != nil { + return fmt.Errorf("Error marshalling params to JSON, %w", err) + } + + _, err = api.makeRequest(ctx, http.MethodPost, FloatingIPsURI, requestBody) + if err != nil { + return err + } + + return nil +} + +// DeleteFloatingIP deletes FloatingIP from provided instance of an existing datastore. +func (api *API) DeleteFloatingIP(ctx context.Context, opts FloatingIPsOpts) error { + floatingIPsOpts := struct { + FloatingIP FloatingIPsOpts `json:"floating-ip"` + }{ + FloatingIP: opts, + } + requestBody, err := json.Marshal(floatingIPsOpts) + if err != nil { + return fmt.Errorf("Error marshalling params to JSON, %w", err) + } + + _, err = api.makeRequest(ctx, http.MethodDelete, FloatingIPsURI, requestBody) + if err != nil { + return err + } + + return nil +} diff --git a/floating_ips_test.go b/floating_ips_test.go new file mode 100644 index 0000000..0a7e60d --- /dev/null +++ b/floating_ips_test.go @@ -0,0 +1,76 @@ +package dbaas + +import ( + "context" + "fmt" + "testing" + + "github.com/jarcoal/httpmock" + "github.com/stretchr/testify/require" +) + +const testInstanceNotFoundResponse = `{ + "error": { + "code": 404, + "title": "Not Found", + "message": "instance %s not found." + } +}` + +const instanceID = "7d959e48-4d42-41cd-8515-aae0a8482d8d" + +func TestCreateFloatingIP(t *testing.T) { + httpmock.Activate() + testClient := SetupTestClient() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("POST", testClient.Endpoint+FloatingIPsURI, + httpmock.NewStringResponder(200, "")) + + createFloatingIPOpts := FloatingIPsOpts{ + InstanceID: instanceID, + } + + err := testClient.CreateFloatingIP(context.Background(), createFloatingIPOpts) + + require.NoError(t, err) +} + +func TestDeleteFloatingIP(t *testing.T) { + httpmock.Activate() + testClient := SetupTestClient() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("DELETE", testClient.Endpoint+FloatingIPsURI, + httpmock.NewStringResponder(200, "")) + + deleteFloatingIPOpts := FloatingIPsOpts{ + InstanceID: instanceID, + } + + err := testClient.DeleteFloatingIP(context.Background(), deleteFloatingIPOpts) + + require.NoError(t, err) +} + +func TestCreateFloatingIPInstanceNotFound(t *testing.T) { + httpmock.Activate() + testClient := SetupTestClient() + defer httpmock.DeactivateAndReset() + + httpmock.RegisterResponder("DELETE", testClient.Endpoint+FloatingIPsURI, + httpmock.NewStringResponder(404, testInstanceNotFoundResponse)) + + createFloatingIPOpts := FloatingIPsOpts{ + InstanceID: instanceID, + } + + expected := &DBaaSAPIError{} + expected.APIError.Code = 404 + expected.APIError.Title = ErrorNotFoundTitle + expected.APIError.Message = fmt.Sprintf("instance %s not found.", instanceID) + + err := testClient.DeleteFloatingIP(context.Background(), createFloatingIPOpts) + + require.ErrorAs(t, err, &expected) +}