Skip to content

Commit

Permalink
Merge pull request #1046 from wisererik/host-dev
Browse files Browse the repository at this point in the history
Add host api implementation
  • Loading branch information
kumarashit authored Nov 15, 2019
2 parents 3dab5dc + df1842e commit d83dcc0
Show file tree
Hide file tree
Showing 19 changed files with 1,688 additions and 9 deletions.
2 changes: 2 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type Client struct {
*VersionMgr
*ReplicationMgr
*FileShareMgr
*HostMgr

cfg *Config
}
Expand Down Expand Up @@ -98,6 +99,7 @@ func NewClient(c *Config) (*Client, error) {
VersionMgr: NewVersionMgr(r, c.Endpoint, t),
ReplicationMgr: NewReplicationMgr(r, c.Endpoint, t),
FileShareMgr: NewFileShareMgr(r, c.Endpoint, t),
HostMgr: NewHostMgr(r, c.Endpoint, t),
}, nil
}

Expand Down
48 changes: 48 additions & 0 deletions client/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ func NewFakeClient(config *Config) *Client {
Receiver: NewFakeFileShareReceiver(),
Endpoint: config.Endpoint,
},
HostMgr: &HostMgr{
Receiver: NewFakeHostReceiver(),
Endpoint: config.Endpoint,
},
}
})
return fakeClient
Expand Down Expand Up @@ -440,3 +444,47 @@ func (*fakeFileShareReceiver) Recv(

return nil
}

func NewFakeHostReceiver() Receiver {
return &fakeHostReceiver{}
}

type fakeHostReceiver struct{}

func (*fakeHostReceiver) Recv(
string,
method string,
in interface{},
out interface{},
) error {
switch strings.ToUpper(method) {
case "POST", "PUT":
switch out.(type) {
case *model.HostSpec:
if err := json.Unmarshal([]byte(ByteHost), out); err != nil {
return err
}
default:
return errors.New("output format not supported")
}
case "GET":
switch out.(type) {
case *model.HostSpec:
if err := json.Unmarshal([]byte(ByteHost), out); err != nil {
return err
}
case *[]*model.HostSpec:
if err := json.Unmarshal([]byte(ByteHosts), out); err != nil {
return err
}
default:
return errors.New("output format not supported")
}
case "DELETE":
break
default:
return errors.New("inputed method format not supported")
}

return nil
}
115 changes: 115 additions & 0 deletions client/host.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright 2019 The OpenSDS Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
"strings"

"github.com/opensds/opensds/pkg/model"
"github.com/opensds/opensds/pkg/utils/urls"
)

// HostBuilder contains request body of handling a host request.
type HostBuilder *model.HostSpec

// NewHostMgr implementation
func NewHostMgr(r Receiver, edp string, tenantID string) *HostMgr {
return &HostMgr{
Receiver: r,
Endpoint: edp,
TenantID: tenantID,
}
}

// HostMgr implementation
type HostMgr struct {
Receiver
Endpoint string
TenantID string
}

// CreateHost implementation
func (h *HostMgr) CreateHost(body HostBuilder) (*model.HostSpec, error) {
var res model.HostSpec

url := strings.Join([]string{
h.Endpoint,
urls.GenerateHostURL(urls.Client, h.TenantID)}, "/")

if err := h.Recv(url, "POST", body, &res); err != nil {
return nil, err
}

return &res, nil
}

// GetHost implementation
func (h *HostMgr) GetHost(ID string) (*model.HostSpec, error) {
var res model.HostSpec
url := strings.Join([]string{
h.Endpoint,
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")

if err := h.Recv(url, "GET", nil, &res); err != nil {
return nil, err
}

return &res, nil
}

// ListHosts implementation
func (h *HostMgr) ListHosts(args ...interface{}) ([]*model.HostSpec, error) {
url := strings.Join([]string{
h.Endpoint,
urls.GenerateHostURL(urls.Client, h.TenantID)}, "/")

param, err := processListParam(args)
if err != nil {
return nil, err
}

if param != "" {
url += "?" + param
}

var res []*model.HostSpec
if err := h.Recv(url, "GET", nil, &res); err != nil {
return nil, err
}
return res, nil
}

// UpdateHost implementation
func (h *HostMgr) UpdateHost(ID string, body HostBuilder) (*model.HostSpec, error) {
var res model.HostSpec
url := strings.Join([]string{
h.Endpoint,
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")

if err := h.Recv(url, "PUT", body, &res); err != nil {
return nil, err
}

return &res, nil
}

// DeleteHost implementation
func (h *HostMgr) DeleteHost(ID string) error {
url := strings.Join([]string{
h.Endpoint,
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")

return h.Recv(url, "DELETE", nil, nil)
}
204 changes: 204 additions & 0 deletions client/host_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
// Copyright 2019 The OpenSDS Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package client

import (
"reflect"
"testing"

"github.com/opensds/opensds/pkg/model"
)

var fakeHostMgr = &HostMgr{
Receiver: NewFakeHostReceiver(),
}

func TestCreateHost(t *testing.T) {
expected := &model.HostSpec{
BaseModel: &model.BaseModel{
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
CreatedAt: "2019-11-11T11:01:33",
},
TenantId: "x",
AccessMode: "agentless",
HostName: "sap1",
IP: "192.168.56.12",
AvailabilityZones: []string{"az1", "az2"},
Initiators: []*model.Initiator{
&model.Initiator{
PortName: "20000024ff5bb888",
Protocol: "iscsi",
},
&model.Initiator{
PortName: "20000024ff5bc999",
Protocol: "iscsi",
},
},
}

host, err := fakeHostMgr.CreateHost(&model.HostSpec{})
if err != nil {
t.Error(err)
return
}

if !reflect.DeepEqual(host, expected) {
t.Errorf("expected %+v, got %+v", expected, host)
return
}
}

func TestGetHost(t *testing.T) {
hostID := "d2975ebe-d82c-430f-b28e-f373746a71ca"
expected := &model.HostSpec{
BaseModel: &model.BaseModel{
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
CreatedAt: "2019-11-11T11:01:33",
},
TenantId: "x",
AccessMode: "agentless",
HostName: "sap1",
IP: "192.168.56.12",
AvailabilityZones: []string{"az1", "az2"},
Initiators: []*model.Initiator{
&model.Initiator{
PortName: "20000024ff5bb888",
Protocol: "iscsi",
},
&model.Initiator{
PortName: "20000024ff5bc999",
Protocol: "iscsi",
},
},
}

host, err := fakeHostMgr.GetHost(hostID)
if err != nil {
t.Error(err)
return
}

if !reflect.DeepEqual(host, expected) {
t.Errorf("expected %v, got %v", expected, host)
return
}
}

func TestListHosts(t *testing.T) {
sampleHosts := []model.HostSpec{
{
BaseModel: &model.BaseModel{
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
CreatedAt: "2019-11-11T11:01:33",
},
TenantId: "x",
AccessMode: "agentless",
HostName: "sap1",
IP: "192.168.56.12",
AvailabilityZones: []string{"az1", "az2"},
Initiators: []*model.Initiator{
&model.Initiator{
PortName: "20000024ff5bb888",
Protocol: "iscsi",
},
&model.Initiator{
PortName: "20000024ff5bc999",
Protocol: "iscsi",
},
},
},
{
BaseModel: &model.BaseModel{
Id: "eb73e59a-8b0f-4517-8b95-023ec134aec9",
CreatedAt: "2019-11-11T11:13:57",
},
TenantId: "x",
AccessMode: "agentless",
HostName: "sap2",
IP: "192.168.56.13",
AvailabilityZones: []string{"az1", "az2"},
Initiators: []*model.Initiator{
&model.Initiator{
PortName: "20012324ff5ac132",
Protocol: "iscsi",
},
},
},
}

var expected []*model.HostSpec
expected = append(expected, &sampleHosts[0])
expected = append(expected, &sampleHosts[1])
hosts, err := fakeHostMgr.ListHosts(map[string]string{"limit": "0", "offset": "10"})

if err != nil {
t.Error(err)
return
}

if !reflect.DeepEqual(hosts, expected) {
t.Errorf("expected %v, got %v", expected, hosts)
return
}
}

func TestUpdateHost(t *testing.T) {
hostID := "202964b5-8e73-46fd-b41b-a8e403f3c30b"
host := &model.HostSpec{
HostName: "sap1-updated",
}

result, err := fakeHostMgr.UpdateHost(hostID, host)
if err != nil {
t.Error(err)
return
}

expected := &model.HostSpec{
BaseModel: &model.BaseModel{
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
CreatedAt: "2019-11-11T11:01:33",
},
TenantId: "x",
AccessMode: "agentless",
HostName: "sap1",
IP: "192.168.56.12",
AvailabilityZones: []string{"az1", "az2"},
Initiators: []*model.Initiator{
&model.Initiator{
PortName: "20000024ff5bb888",
Protocol: "iscsi",
},
&model.Initiator{
PortName: "20000024ff5bc999",
Protocol: "iscsi",
},
},
}

if !reflect.DeepEqual(result, expected) {
t.Errorf("expected %v, got %v", expected, result)
return
}
}

func TestDeleteHost(t *testing.T) {
var hostID = "d202964b5-8e73-46fd-b41b-a8e403f3c30b"

if err := fakeHostMgr.DeleteHost(hostID); err != nil {
t.Error(err)
return
}
}
Loading

0 comments on commit d83dcc0

Please sign in to comment.