Skip to content

Commit

Permalink
Merge branch 'develop' into event
Browse files Browse the repository at this point in the history
  • Loading branch information
nvthongswansea committed Aug 30, 2019
2 parents a4bcfc5 + 3ac767f commit 27b8722
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 14 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -211,6 +211,10 @@ Not all endpoints have been implemented in this client, but new ones will be add
* Firewall Events Get (GetFirewallEventList)
* Event
* Events Get (GetEventList)
* Label
* Labels Get (GetLabelList)
* Label Create (CreateLabel)
* Label Delete (DeleteLabel)
* Location
* Locations Get (GetLocationList)
* Location Get (GetLocation)
Expand Down
1 change: 1 addition & 0 deletions client.go
Expand Up @@ -14,6 +14,7 @@ const (
apiFirewallBase = "/objects/firewalls"
apiLocationBase = "/objects/locations"
apiEventBase = "/objects/events"
apiLabelBase = "/objects/labels"
apiDeletedBase = "/objects/deleted"
)

Expand Down
55 changes: 55 additions & 0 deletions examples/label.go
@@ -0,0 +1,55 @@
package main

import (
"bufio"
"github.com/nvthongswansea/gsclient-go"
log "github.com/sirupsen/logrus"
"os"
)

func main() {
uuid := os.Getenv("GRIDSCALE_UUID")
token := os.Getenv("GRIDSCALE_TOKEN")
config := gsclient.NewConfiguration(
"https://api.gridscale.io",
uuid,
token,
true,
)
client := gsclient.NewClient(config)
log.Info("gridscale client configured")

log.Info("Create label: Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

_, err := client.CreateLabel(gsclient.LabelCreateRequest{
Label: "go-client-label",
})
if err != nil {
log.Error("Create label has failed with error", err)
return
}
log.Info("Label successfully created")
defer func() {
err := client.DeleteLabel("go-client-label")
if err != nil {
log.Error("Delete label has failed with error", err)
return
}
}()

log.Info("Retrieve labels: Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')

labels, err := client.GetLabelList()
if err != nil {
log.Error("Retrieve labels has failed with error", err)
return
}
log.WithFields(log.Fields{
"labels": labels,
}).Info("Labels successfully retrieved")

log.Info("Delete label: Press 'Enter' to continue...")
bufio.NewReader(os.Stdin).ReadBytes('\n')
}
70 changes: 70 additions & 0 deletions label.go
@@ -0,0 +1,70 @@
package gsclient

import (
"net/http"
"path"
)

//LabelList JSON struct of a list of labels
type LabelList struct {
List map[string]LabelProperties `json:"labels"`
}

//Label JSON struct of a single label
type Label struct {
Properties LabelProperties `json:"label"`
}

//LabelProperties JSON struct of properties of a label
type LabelProperties struct {
Label string `json:"label"`
CreateTime string `json:"create_time"`
ChangeTime string `json:"change_time"`
Relations []interface{} `json:"relations"`
Status string `json:"status"`
}

//LabelCreateRequest JSON struct of a request for creating a label
type LabelCreateRequest struct {
Label string `json:"label"`
}

//GetLabelList gets a list of available labels
func (c *Client) GetLabelList() ([]Label, error) {
r := Request{
uri: apiLabelBase,
method: http.MethodGet,
}
var response LabelList
var labels []Label
err := r.execute(*c, &response)
for _, properties := range response.List {
labels = append(labels, Label{Properties: properties})
}
return labels, err
}

//CreateLabel creates a new label
func (c *Client) CreateLabel(body LabelCreateRequest) (CreateResponse, error) {
r := Request{
uri: apiLabelBase,
method: http.MethodPost,
body: body,
}
var response CreateResponse
err := r.execute(*c, &response)
if err != nil {
return CreateResponse{}, err
}
err = c.WaitForRequestCompletion(response.RequestUUID)
return response, err
}

//DeleteLabel deletes a label
func (c *Client) DeleteLabel(label string) error {
r := Request{
uri: path.Join(apiLabelBase, label),
method: http.MethodDelete,
}
return r.execute(*c, nil)
}
89 changes: 89 additions & 0 deletions label_test.go
@@ -0,0 +1,89 @@
package gsclient

import (
"encoding/json"
"fmt"
"github.com/stretchr/testify/assert"
"net/http"
"path"
"testing"
)

func TestClient_GetLabelList(t *testing.T) {
server, client, mux := setupTestClient()
defer server.Close()
uri := apiLabelBase
mux.HandleFunc(uri, func(writer http.ResponseWriter, request *http.Request) {
assert.Equal(t, http.MethodGet, request.Method)
fmt.Fprintf(writer, prepareLabelListHTTPGet())
})
res, err := client.GetLabelList()
if err != nil {
t.Errorf("GetLabelList returned an error %v", err)
}
assert.Equal(t, 1, len(res))
assert.Equal(t, fmt.Sprintf("[%v]", getMockLabel()), fmt.Sprintf("%v", res))
}

func TestClient_CreateLabel(t *testing.T) {
server, client, mux := setupTestClient()
defer server.Close()
uri := apiLabelBase
mux.HandleFunc(uri, func(writer http.ResponseWriter, request *http.Request) {
assert.Equal(t, http.MethodPost, request.Method)
fmt.Fprint(writer, prepareLabelCreateResponse())
})
httpResponse := fmt.Sprintf(`{"%s": {"status":"done"}}`, dummyRequestUUID)
mux.HandleFunc("/requests/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, httpResponse)
})
res, err := client.CreateLabel(LabelCreateRequest{Label: "test"})
if err != nil {
t.Errorf("CreateLabel returned an error %v", err)
}
assert.Equal(t, fmt.Sprintf("%v", getMockLabelCreateResponse()), fmt.Sprintf("%v", res))
}

func TestClient_DeleteLabel(t *testing.T) {
server, client, mux := setupTestClient()
defer server.Close()
uri := path.Join(apiLabelBase, "test")
mux.HandleFunc(uri, func(writer http.ResponseWriter, request *http.Request) {
assert.Equal(t, http.MethodDelete, request.Method)
fmt.Fprint(writer, "")
})
err := client.DeleteLabel("test")
if err != nil {
t.Errorf("DeleteLabel returned an error %v", err)
}
}

func getMockLabel() Label {
mock := Label{Properties: LabelProperties{
Label: "test",
CreateTime: dummyTime,
ChangeTime: dummyTime,
Relations: nil,
Status: "active",
}}
return mock
}

func getMockLabelCreateResponse() CreateResponse {
mock := CreateResponse{
RequestUUID: dummyRequestUUID,
}
return mock
}

func prepareLabelListHTTPGet() string {
label := getMockLabel()
res, _ := json.Marshal(label.Properties)
return fmt.Sprintf(`{"labels": {"%s": %s}}`, dummyUUID, string(res))
}

func prepareLabelCreateResponse() string {
response := getMockLabelCreateResponse()
res, _ := json.Marshal(response)
return string(res)
}
3 changes: 3 additions & 0 deletions loadbalancer.go
Expand Up @@ -114,6 +114,9 @@ func (c *Client) GetLoadBalancer(id string) (LoadBalancer, error) {

//CreateLoadBalancer creates a new loadbalancer
func (c *Client) CreateLoadBalancer(body LoadBalancerCreateRequest) (LoadBalancerCreateResponse, error) {
if body.Labels == nil {
body.Labels = make([]string, 0)
}
r := Request{
uri: apiLoadBalancerBase,
method: http.MethodPost,
Expand Down
50 changes: 37 additions & 13 deletions server.go
Expand Up @@ -51,15 +51,24 @@ type ServerRelations struct {

//ServerCreateRequest JSON struct of a request for creating a server
type ServerCreateRequest struct {
Name string `json:"name"`
Memory int `json:"memory"`
Cores int `json:"cores"`
LocationUUID string `json:"location_uuid"`
HardwareProfile string `json:"hardware_profile,omitempty"`
AvailablityZone string `json:"availability_zone,omitempty"`
Labels []string `json:"labels,omitempty"`
Status string `json:"status,omitempty"`
AutoRecovery *bool `json:"auto_recovery,omitempty"`
Name string `json:"name"`
Memory int `json:"memory"`
Cores int `json:"cores"`
LocationUUID string `json:"location_uuid"`
HardwareProfile string `json:"hardware_profile,omitempty"`
AvailablityZone string `json:"availability_zone,omitempty"`
Labels []string `json:"labels,omitempty"`
Status string `json:"status,omitempty"`
AutoRecovery *bool `json:"auto_recovery,omitempty"`
Relations ServerCreateRequestRelations `json:"relations"`
}

//ServerCreateRequestRelations JSOn struct of a list of a server's relations
type ServerCreateRequestRelations struct {
IsoImages []ServerCreateRequestIsoimage `json:"isoimages"`
Networks []ServerCreateRequestNetwork `json:"networks"`
PublicIPs []ServerCreateRequestIP `json:"public_ips"`
Storages []ServerCreateRequestStorage `json:"storages"`
}

//ServerCreateResponse JSON struct of a response for creating a server
Expand All @@ -79,24 +88,24 @@ type ServerPowerUpdateRequest struct {

//ServerCreateRequestStorage JSON struct of a relation between a server and a storage
type ServerCreateRequestStorage struct {
StorageUUID string `json:"storage_uuid,omitempty"`
StorageUUID string `json:"storage_uuid"`
BootDevice bool `json:"bootdevice,omitempty"`
}

//ServerCreateRequestNetwork JSON struct of a relation between a server and a network
type ServerCreateRequestNetwork struct {
NetworkUUID string `json:"network_uuid,omitempty"`
NetworkUUID string `json:"network_uuid"`
BootDevice bool `json:"bootdevice,omitempty"`
}

//ServerCreateRequestIP JSON struct of a relation between a server and an IP address
type ServerCreateRequestIP struct {
IPaddrUUID string `json:"ipaddr_uuid,omitempty"`
IPaddrUUID string `json:"ipaddr_uuid"`
}

//ServerCreateRequestIsoimage JSON struct of a relation between a server and an ISO-Image
type ServerCreateRequestIsoimage struct {
IsoimageUUID string `json:"isoimage_uuid,omitempty"`
IsoimageUUID string `json:"isoimage_uuid"`
}

//ServerUpdateRequest JSON of a request for updating a server
Expand Down Expand Up @@ -164,6 +173,21 @@ func (c *Client) GetServerList() ([]Server, error) {

//CreateServer create a server
func (c *Client) CreateServer(body ServerCreateRequest) (ServerCreateResponse, error) {
//check if these slices are nil
//make them be empty slice instead of nil
//so that JSON structure will be valid
if body.Relations.PublicIPs == nil {
body.Relations.PublicIPs = make([]ServerCreateRequestIP, 0)
}
if body.Relations.Networks == nil {
body.Relations.Networks = make([]ServerCreateRequestNetwork, 0)
}
if body.Relations.IsoImages == nil {
body.Relations.IsoImages = make([]ServerCreateRequestIsoimage, 0)
}
if body.Relations.Storages == nil {
body.Relations.Storages = make([]ServerCreateRequestStorage, 0)
}
r := Request{
uri: apiServerBase,
method: http.MethodPost,
Expand Down
2 changes: 1 addition & 1 deletion server_test.go
Expand Up @@ -225,7 +225,7 @@ func TestClient_ShutdownServer(t *testing.T) {
assert.Equal(t, http.MethodPatch, request.Method)
power = false
writer.WriteHeader(http.StatusInternalServerError)
writer.Write([]byte("☄ HTTP status code returned!"))
writer.Write([]byte("☄ HTTP status code returned!"))
fmt.Fprint(writer, "")
})

Expand Down

0 comments on commit 27b8722

Please sign in to comment.