Skip to content

Commit

Permalink
GCLOUD2-16682 Added metadata item support for instances (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
TheSimonSays authored Nov 27, 2024
1 parent 9e3715e commit 1852739
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 0 deletions.
52 changes: 52 additions & 0 deletions gcore/instance/v2/instances/requests.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package instances

import (
"net/http"

gcorecloud "github.com/G-Core/gcorelabscloud-go"
"github.com/G-Core/gcorelabscloud-go/gcore/instance/v2/types"
"github.com/G-Core/gcorelabscloud-go/gcore/task/v1/tasks"
"github.com/G-Core/gcorelabscloud-go/gcore/utils/metadata"
)

// ActionOptsBuilder allows extensions to add parameters to the action request.
Expand Down Expand Up @@ -44,3 +47,52 @@ func Action(client *gcorecloud.ServiceClient, instanceID string, opts ActionOpts
_, r.Err = client.Post(resourceActionURL(client, instanceID), b, &r.Body, nil) // nolint
return
}

// MetadataItemOpts represents options used to find a metadata.
type MetadataItemOpts struct {
Key string `q:"key" validate:"required"`
}

type MetadataItemBuilder interface {
ToMetadataItemQuery() (string, error)
}

// ToMetadataItemQuery builds a query string from MetadataItemOpts.
func (opts MetadataItemOpts) ToMetadataItemQuery() (string, error) {
if err := gcorecloud.ValidateStruct(opts); err != nil {
return "", err
}
q, err := gcorecloud.BuildQueryString(opts)
if err != nil {
return "", err
}
return q.String(), err
}

// MetadataItemGet gets defined metadata key for an instance.
func MetadataItemGet(client *gcorecloud.ServiceClient, id string, opts MetadataItemOpts) (r metadata.MetadataResult) {
url := metadataItemURL(client, id)
query, err := opts.ToMetadataItemQuery()
if err != nil {
r.Err = err
return
}
url += query
_, r.Err = client.Get(url, &r.Body, nil) // nolint
return
}

// MetadataItemDelete deletes defined metadata key for an instance.
func MetadataItemDelete(client *gcorecloud.ServiceClient, id string, opts MetadataItemOpts) (r metadata.MetadataActionResult) {
url := metadataItemURL(client, id)
query, err := opts.ToMetadataItemQuery()
if err != nil {
r.Err = err
return
}
url += query
_, r.Err = client.Delete(url, &gcorecloud.RequestOpts{ // nolint
OkCodes: []int{http.StatusNoContent, http.StatusOK},
})
return
}
1 change: 1 addition & 0 deletions gcore/instance/v2/instances/testing/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package testing
22 changes: 22 additions & 0 deletions gcore/instance/v2/instances/testing/fixtures.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package testing

import (
"github.com/G-Core/gcorelabscloud-go/gcore/utils/metadata"
)

const MetadataResponse = `
{
"key": "db.name",
"value": "pg",
"read_only": false
}
`

var (
instanceID = "ad1bb86e-2f83-4e0f-87c0-e1fd777d6352"
Metadata = metadata.Metadata{
Key: "db.name",
Value: "pg",
ReadOnly: false,
}
)
17 changes: 17 additions & 0 deletions gcore/instance/v2/instances/testing/metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package testing

import (
"testing"

instancesV2 "github.com/G-Core/gcorelabscloud-go/gcore/instance/v2/instances"
"github.com/stretchr/testify/require"
)

func TestMetadataItemEmptyParam(t *testing.T) {
opts := instancesV2.MetadataItemOpts{
Key: "",
}
_, err := opts.ToMetadataItemQuery()
require.Error(t, err)
require.Contains(t, err.Error(), "Key is a required field")
}
57 changes: 57 additions & 0 deletions gcore/instance/v2/instances/testing/requests_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package testing

import (
"fmt"
"net/http"
"testing"

instancesV2 "github.com/G-Core/gcorelabscloud-go/gcore/instance/v2/instances"
th "github.com/G-Core/gcorelabscloud-go/testhelper"
fake "github.com/G-Core/gcorelabscloud-go/testhelper/client"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)

func prepareMetadataItemTestURL(id string) string {
return fmt.Sprintf("/%s/instances/%d/%d/%s/%s", "v2", fake.ProjectID, fake.RegionID, id, "metadata_item")
}

func TestMetadataItemGet(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc(prepareMetadataItemTestURL(instanceID), func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "GET")
th.TestHeader(t, r, "Authorization", fmt.Sprintf("Bearer %s", fake.AccessToken))

w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
_, err := fmt.Fprint(w, MetadataResponse)
if err != nil {
log.Error(err)
}
})

client := fake.ServiceTokenClient("instances", "v2")

actual, err := instancesV2.MetadataItemGet(client, instanceID, instancesV2.MetadataItemOpts{Key: Metadata.Key}).Extract()
require.NoError(t, err)
require.Equal(t, &Metadata, actual)
}

func TestMetadataItemDelete(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc(prepareMetadataItemTestURL(instanceID), func(w http.ResponseWriter, r *http.Request) {
th.TestMethod(t, r, "DELETE")
th.TestHeader(t, r, "Authorization", fmt.Sprintf("Bearer %s", fake.AccessToken))
th.TestHeader(t, r, "Accept", "application/json")
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(http.StatusNoContent)
})

client := fake.ServiceTokenClient("instances", "v2")
err := instancesV2.MetadataItemDelete(client, instanceID, instancesV2.MetadataItemOpts{Key: Metadata.Key}).ExtractErr()
require.NoError(t, err)
}
4 changes: 4 additions & 0 deletions gcore/instance/v2/instances/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ import gcorecloud "github.com/G-Core/gcorelabscloud-go"
func resourceActionURL(c *gcorecloud.ServiceClient, id string) string {
return c.ServiceURL(id, "action")
}

func metadataItemURL(c *gcorecloud.ServiceClient, id string) string {
return c.ServiceURL(id, "metadata_item")
}

0 comments on commit 1852739

Please sign in to comment.