Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,10 @@ type idNameRoot struct {
Count int
IDNames []IDName `json:"results"`
}

type SortOrder string

const (
SortOrderDesc SortOrder = "desc"
SortOrderAsc SortOrder = "asc"
)
117 changes: 117 additions & 0 deletions mkaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
type MKaaSService interface {
MKaaSClusters
MKaaSPools
MKaaSNodes
}

type MKaaSClusters interface {
Expand All @@ -26,6 +27,32 @@ type MKaaSClusters interface {
ClusterDelete(context.Context, int) (*TaskResponse, *Response, error)
}

type NodeState string

const (
NodeStatePending NodeState = "PENDING"
NodeStateCreating NodeState = "CREATING"
NodeStateReady NodeState = "READY"
NodeStateFailed NodeState = "FAILED"
NodeStateScheduledDelete NodeState = "SCHEDULED_TO_DELETE"
NodeStateDeleting NodeState = "DELETING"
NodeStateDeleted NodeState = "DELETED"
)

type NodeSortKey string

const (
NodeSortKeyID NodeSortKey = "id"
NodeSortKeyName NodeSortKey = "name"
NodeSortKeyCreatedAt NodeSortKey = "created_at"
NodeSortKeySequenceNumber NodeSortKey = "sequence_number"
)

type MKaaSNodes interface {
NodesList(ctx context.Context, clusterID, poolID int, opts *MKaaSNodeListOptions) ([]MKaaSNode, *Response, error)
NodeDelete(ctx context.Context, clusterID, poolID, nodeID int) (*TaskResponse, *Response, error)
}

type MKaaSPools interface {
PoolCreate(ctx context.Context, clusterID int, reqBody MKaaSPoolCreateRequest) (*TaskResponse, *Response, error)
PoolsList(ctx context.Context, clusterID int, opts *MKaaSPoolListOptions) ([]MKaaSPool, *Response, error)
Expand Down Expand Up @@ -56,6 +83,31 @@ type MKaaSPoolsRoot struct {
Pools []MKaaSPool `json:"results"`
}

type MKaaSNodesList struct {
Nodes []MKaaSNode `json:"nodes"`
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
}

type MKaaSNode struct {
ID int `json:"id"`
Name string `json:"name"`
PoolID int `json:"pool_id"`
State NodeState `json:"state"`
Status string `json:"status"`
IPAddress string `json:"ip_address"`
CreatedAt string `json:"created_at"`
}

type MKaaSNodeListOptions struct {
State NodeState `url:"state,omitempty"`
Limit int `url:"limit,omitempty"`
Offset int `url:"offset,omitempty"`
SortBy NodeSortKey `url:"sort_by,omitempty"`
SortOrder SortOrder `url:"sort_order,omitempty"`
}

type MKaaSClusterListOptions struct {
Name string `url:"name,omitempty"`
Status string `url:"status,omitempty"`
Expand Down Expand Up @@ -514,3 +566,68 @@ func (m *MKaaSServiceOp) PoolUpdateLabels(

return tasks, resp, err
}

func (m *MKaaSServiceOp) NodesList(
ctx context.Context, clusterID, poolID int, opts *MKaaSNodeListOptions,
) ([]MKaaSNode, *Response, error) {
if resp, err := m.client.Validate(); err != nil {
return nil, resp, err
}

path := fmt.Sprintf(
"%s/%d/pools/%d/nodes",
m.client.addProjectRegionPath(MKaaSClustersBasePathV2),
clusterID,
poolID,
)
path, err := addOptions(path, opts)
if err != nil {
return nil, nil, err
}

req, err := m.client.NewRequest(ctx, http.MethodGet, path, nil)
if err != nil {
return nil, nil, err
}

root := new(MKaaSNodesList)
resp, err := m.client.Do(ctx, req, root)
if err != nil {
return nil, resp, err
}

if root.Nodes == nil {
return []MKaaSNode{}, resp, nil
}

return root.Nodes, resp, nil
}

func (m *MKaaSServiceOp) NodeDelete(
ctx context.Context, clusterID, poolID, nodeID int,
) (*TaskResponse, *Response, error) {
if resp, err := m.client.Validate(); err != nil {
return nil, resp, err
}

path := fmt.Sprintf(
"%s/%d/pools/%d/nodes/%d",
m.client.addProjectRegionPath(MKaaSClustersBasePathV2),
clusterID,
poolID,
nodeID,
)

req, err := m.client.NewRequest(ctx, http.MethodDelete, path, nil)
if err != nil {
return nil, nil, err
}

tasks := new(TaskResponse)
resp, err := m.client.Do(ctx, req, tasks)
if err != nil {
return nil, resp, err
}

return tasks, resp, err
}
82 changes: 82 additions & 0 deletions mkaas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
mkaasKeypairName = "keypair"
mkaasFlavor = "g1-standard-2-4"
mkaasVersion = "v1.31.0"
mkaasTestPoolID = 1099
)

func TestMKaaSServiceOp_ClusterCreate(t *testing.T) {
Expand Down Expand Up @@ -461,3 +462,84 @@ func TestMKaaSServiceOp_PoolUpdateLabels(t *testing.T) {
require.Equal(t, resp.StatusCode, 200)
require.Equal(t, respActual, expectedResp)
}

func TestMKaaSServiceOp_NodesList(t *testing.T) {
setup()
defer teardown()

expectedResp := []MKaaSNode{{ID: testResourceIntID, Name: "test-node", PoolID: mkaasTestPoolID, State: NodeStateReady}}
URL := path.Join(MKaaSClustersBasePathV2, strconv.Itoa(projectID), strconv.Itoa(regionID),
strconv.Itoa(testResourceIntID), "pools", strconv.Itoa(mkaasTestPoolID), "nodes")

mux.HandleFunc(URL, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
resp, err := json.Marshal(expectedResp)
if err != nil {
t.Errorf("failed to marshal response: %v", err)
}
_, _ = fmt.Fprintf(w, `{"nodes":%s}`, string(resp))
})

respActual, resp, err := client.MkaaS.NodesList(ctx, testResourceIntID, mkaasTestPoolID, nil)
require.NoError(t, err)
require.Equal(t, resp.StatusCode, 200)
require.Equal(t, respActual, expectedResp)
}

func TestMKaaSServiceOp_NodeDelete(t *testing.T) {
setup()
defer teardown()

const testNodeID = testResourceIntID + 1

expectedResp := &TaskResponse{Tasks: []string{taskID}}
URL := path.Join(MKaaSClustersBasePathV2, strconv.Itoa(projectID), strconv.Itoa(regionID),
strconv.Itoa(testResourceIntID), "pools", strconv.Itoa(mkaasTestPoolID), "nodes", strconv.Itoa(testNodeID))

mux.HandleFunc(URL, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodDelete)
resp, err := json.Marshal(expectedResp)
if err != nil {
t.Errorf("failed to marshal response: %v", err)
}
_, _ = fmt.Fprint(w, string(resp))
})

respActual, resp, err := client.MkaaS.NodeDelete(ctx, testResourceIntID, mkaasTestPoolID, testNodeID)
require.NoError(t, err)
require.Equal(t, resp.StatusCode, 200)
require.Equal(t, respActual, expectedResp)
}

func TestMKaaSServiceOp_NodesList_WithOptions(t *testing.T) {
setup()
defer teardown()

expectedResp := []MKaaSNode{{ID: testResourceIntID, Name: "test-node", PoolID: mkaasTestPoolID, State: NodeStateReady}}
URL := path.Join(MKaaSClustersBasePathV2, strconv.Itoa(projectID), strconv.Itoa(regionID),
strconv.Itoa(testResourceIntID), "pools", strconv.Itoa(mkaasTestPoolID), "nodes")

mux.HandleFunc(URL, func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
assert.Equal(t, r.URL.Query().Get("state"), string(NodeStateReady))
assert.Equal(t, r.URL.Query().Get("limit"), "10")
assert.Equal(t, r.URL.Query().Get("sort_by"), string(NodeSortKeyName))
assert.Equal(t, r.URL.Query().Get("sort_order"), string(SortOrderAsc))
resp, err := json.Marshal(expectedResp)
if err != nil {
t.Errorf("failed to marshal response: %v", err)
}
_, _ = fmt.Fprintf(w, `{"nodes":%s}`, string(resp))
})

opts := &MKaaSNodeListOptions{
State: NodeStateReady,
Limit: 10,
SortBy: NodeSortKeyName,
SortOrder: SortOrderAsc,
}
respActual, resp, err := client.MkaaS.NodesList(ctx, testResourceIntID, mkaasTestPoolID, opts)
require.NoError(t, err)
require.Equal(t, resp.StatusCode, 200)
require.Equal(t, respActual, expectedResp)
}
Loading