Skip to content

Commit df1842e

Browse files
committed
Add client and cli for host API
1 parent cb45fd9 commit df1842e

15 files changed

Lines changed: 992 additions & 20 deletions

File tree

client/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type Client struct {
4242
*VersionMgr
4343
*ReplicationMgr
4444
*FileShareMgr
45+
*HostMgr
4546

4647
cfg *Config
4748
}
@@ -98,6 +99,7 @@ func NewClient(c *Config) (*Client, error) {
9899
VersionMgr: NewVersionMgr(r, c.Endpoint, t),
99100
ReplicationMgr: NewReplicationMgr(r, c.Endpoint, t),
100101
FileShareMgr: NewFileShareMgr(r, c.Endpoint, t),
102+
HostMgr: NewHostMgr(r, c.Endpoint, t),
101103
}, nil
102104
}
103105

client/fake.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func NewFakeClient(config *Config) *Client {
6363
Receiver: NewFakeFileShareReceiver(),
6464
Endpoint: config.Endpoint,
6565
},
66+
HostMgr: &HostMgr{
67+
Receiver: NewFakeHostReceiver(),
68+
Endpoint: config.Endpoint,
69+
},
6670
}
6771
})
6872
return fakeClient
@@ -440,3 +444,47 @@ func (*fakeFileShareReceiver) Recv(
440444

441445
return nil
442446
}
447+
448+
func NewFakeHostReceiver() Receiver {
449+
return &fakeHostReceiver{}
450+
}
451+
452+
type fakeHostReceiver struct{}
453+
454+
func (*fakeHostReceiver) Recv(
455+
string,
456+
method string,
457+
in interface{},
458+
out interface{},
459+
) error {
460+
switch strings.ToUpper(method) {
461+
case "POST", "PUT":
462+
switch out.(type) {
463+
case *model.HostSpec:
464+
if err := json.Unmarshal([]byte(ByteHost), out); err != nil {
465+
return err
466+
}
467+
default:
468+
return errors.New("output format not supported")
469+
}
470+
case "GET":
471+
switch out.(type) {
472+
case *model.HostSpec:
473+
if err := json.Unmarshal([]byte(ByteHost), out); err != nil {
474+
return err
475+
}
476+
case *[]*model.HostSpec:
477+
if err := json.Unmarshal([]byte(ByteHosts), out); err != nil {
478+
return err
479+
}
480+
default:
481+
return errors.New("output format not supported")
482+
}
483+
case "DELETE":
484+
break
485+
default:
486+
return errors.New("inputed method format not supported")
487+
}
488+
489+
return nil
490+
}

client/host.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,115 @@
1+
// Copyright 2019 The OpenSDS Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package client
16+
17+
import (
18+
"strings"
19+
20+
"github.com/opensds/opensds/pkg/model"
21+
"github.com/opensds/opensds/pkg/utils/urls"
22+
)
23+
24+
// HostBuilder contains request body of handling a host request.
25+
type HostBuilder *model.HostSpec
26+
27+
// NewHostMgr implementation
28+
func NewHostMgr(r Receiver, edp string, tenantID string) *HostMgr {
29+
return &HostMgr{
30+
Receiver: r,
31+
Endpoint: edp,
32+
TenantID: tenantID,
33+
}
34+
}
35+
36+
// HostMgr implementation
37+
type HostMgr struct {
38+
Receiver
39+
Endpoint string
40+
TenantID string
41+
}
42+
43+
// CreateHost implementation
44+
func (h *HostMgr) CreateHost(body HostBuilder) (*model.HostSpec, error) {
45+
var res model.HostSpec
46+
47+
url := strings.Join([]string{
48+
h.Endpoint,
49+
urls.GenerateHostURL(urls.Client, h.TenantID)}, "/")
50+
51+
if err := h.Recv(url, "POST", body, &res); err != nil {
52+
return nil, err
53+
}
54+
55+
return &res, nil
56+
}
57+
58+
// GetHost implementation
59+
func (h *HostMgr) GetHost(ID string) (*model.HostSpec, error) {
60+
var res model.HostSpec
61+
url := strings.Join([]string{
62+
h.Endpoint,
63+
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")
64+
65+
if err := h.Recv(url, "GET", nil, &res); err != nil {
66+
return nil, err
67+
}
68+
69+
return &res, nil
70+
}
71+
72+
// ListHosts implementation
73+
func (h *HostMgr) ListHosts(args ...interface{}) ([]*model.HostSpec, error) {
74+
url := strings.Join([]string{
75+
h.Endpoint,
76+
urls.GenerateHostURL(urls.Client, h.TenantID)}, "/")
77+
78+
param, err := processListParam(args)
79+
if err != nil {
80+
return nil, err
81+
}
82+
83+
if param != "" {
84+
url += "?" + param
85+
}
86+
87+
var res []*model.HostSpec
88+
if err := h.Recv(url, "GET", nil, &res); err != nil {
89+
return nil, err
90+
}
91+
return res, nil
92+
}
93+
94+
// UpdateHost implementation
95+
func (h *HostMgr) UpdateHost(ID string, body HostBuilder) (*model.HostSpec, error) {
96+
var res model.HostSpec
97+
url := strings.Join([]string{
98+
h.Endpoint,
99+
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")
100+
101+
if err := h.Recv(url, "PUT", body, &res); err != nil {
102+
return nil, err
103+
}
104+
105+
return &res, nil
106+
}
107+
108+
// DeleteHost implementation
109+
func (h *HostMgr) DeleteHost(ID string) error {
110+
url := strings.Join([]string{
111+
h.Endpoint,
112+
urls.GenerateHostURL(urls.Client, h.TenantID, ID)}, "/")
113+
114+
return h.Recv(url, "DELETE", nil, nil)
115+
}

client/host_test.go

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,204 @@
1+
// Copyright 2019 The OpenSDS Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
115
package client
16+
17+
import (
18+
"reflect"
19+
"testing"
20+
21+
"github.com/opensds/opensds/pkg/model"
22+
)
23+
24+
var fakeHostMgr = &HostMgr{
25+
Receiver: NewFakeHostReceiver(),
26+
}
27+
28+
func TestCreateHost(t *testing.T) {
29+
expected := &model.HostSpec{
30+
BaseModel: &model.BaseModel{
31+
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
32+
CreatedAt: "2019-11-11T11:01:33",
33+
},
34+
TenantId: "x",
35+
AccessMode: "agentless",
36+
HostName: "sap1",
37+
IP: "192.168.56.12",
38+
AvailabilityZones: []string{"az1", "az2"},
39+
Initiators: []*model.Initiator{
40+
&model.Initiator{
41+
PortName: "20000024ff5bb888",
42+
Protocol: "iscsi",
43+
},
44+
&model.Initiator{
45+
PortName: "20000024ff5bc999",
46+
Protocol: "iscsi",
47+
},
48+
},
49+
}
50+
51+
host, err := fakeHostMgr.CreateHost(&model.HostSpec{})
52+
if err != nil {
53+
t.Error(err)
54+
return
55+
}
56+
57+
if !reflect.DeepEqual(host, expected) {
58+
t.Errorf("expected %+v, got %+v", expected, host)
59+
return
60+
}
61+
}
62+
63+
func TestGetHost(t *testing.T) {
64+
hostID := "d2975ebe-d82c-430f-b28e-f373746a71ca"
65+
expected := &model.HostSpec{
66+
BaseModel: &model.BaseModel{
67+
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
68+
CreatedAt: "2019-11-11T11:01:33",
69+
},
70+
TenantId: "x",
71+
AccessMode: "agentless",
72+
HostName: "sap1",
73+
IP: "192.168.56.12",
74+
AvailabilityZones: []string{"az1", "az2"},
75+
Initiators: []*model.Initiator{
76+
&model.Initiator{
77+
PortName: "20000024ff5bb888",
78+
Protocol: "iscsi",
79+
},
80+
&model.Initiator{
81+
PortName: "20000024ff5bc999",
82+
Protocol: "iscsi",
83+
},
84+
},
85+
}
86+
87+
host, err := fakeHostMgr.GetHost(hostID)
88+
if err != nil {
89+
t.Error(err)
90+
return
91+
}
92+
93+
if !reflect.DeepEqual(host, expected) {
94+
t.Errorf("expected %v, got %v", expected, host)
95+
return
96+
}
97+
}
98+
99+
func TestListHosts(t *testing.T) {
100+
sampleHosts := []model.HostSpec{
101+
{
102+
BaseModel: &model.BaseModel{
103+
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
104+
CreatedAt: "2019-11-11T11:01:33",
105+
},
106+
TenantId: "x",
107+
AccessMode: "agentless",
108+
HostName: "sap1",
109+
IP: "192.168.56.12",
110+
AvailabilityZones: []string{"az1", "az2"},
111+
Initiators: []*model.Initiator{
112+
&model.Initiator{
113+
PortName: "20000024ff5bb888",
114+
Protocol: "iscsi",
115+
},
116+
&model.Initiator{
117+
PortName: "20000024ff5bc999",
118+
Protocol: "iscsi",
119+
},
120+
},
121+
},
122+
{
123+
BaseModel: &model.BaseModel{
124+
Id: "eb73e59a-8b0f-4517-8b95-023ec134aec9",
125+
CreatedAt: "2019-11-11T11:13:57",
126+
},
127+
TenantId: "x",
128+
AccessMode: "agentless",
129+
HostName: "sap2",
130+
IP: "192.168.56.13",
131+
AvailabilityZones: []string{"az1", "az2"},
132+
Initiators: []*model.Initiator{
133+
&model.Initiator{
134+
PortName: "20012324ff5ac132",
135+
Protocol: "iscsi",
136+
},
137+
},
138+
},
139+
}
140+
141+
var expected []*model.HostSpec
142+
expected = append(expected, &sampleHosts[0])
143+
expected = append(expected, &sampleHosts[1])
144+
hosts, err := fakeHostMgr.ListHosts(map[string]string{"limit": "0", "offset": "10"})
145+
146+
if err != nil {
147+
t.Error(err)
148+
return
149+
}
150+
151+
if !reflect.DeepEqual(hosts, expected) {
152+
t.Errorf("expected %v, got %v", expected, hosts)
153+
return
154+
}
155+
}
156+
157+
func TestUpdateHost(t *testing.T) {
158+
hostID := "202964b5-8e73-46fd-b41b-a8e403f3c30b"
159+
host := &model.HostSpec{
160+
HostName: "sap1-updated",
161+
}
162+
163+
result, err := fakeHostMgr.UpdateHost(hostID, host)
164+
if err != nil {
165+
t.Error(err)
166+
return
167+
}
168+
169+
expected := &model.HostSpec{
170+
BaseModel: &model.BaseModel{
171+
Id: "202964b5-8e73-46fd-b41b-a8e403f3c30b",
172+
CreatedAt: "2019-11-11T11:01:33",
173+
},
174+
TenantId: "x",
175+
AccessMode: "agentless",
176+
HostName: "sap1",
177+
IP: "192.168.56.12",
178+
AvailabilityZones: []string{"az1", "az2"},
179+
Initiators: []*model.Initiator{
180+
&model.Initiator{
181+
PortName: "20000024ff5bb888",
182+
Protocol: "iscsi",
183+
},
184+
&model.Initiator{
185+
PortName: "20000024ff5bc999",
186+
Protocol: "iscsi",
187+
},
188+
},
189+
}
190+
191+
if !reflect.DeepEqual(result, expected) {
192+
t.Errorf("expected %v, got %v", expected, result)
193+
return
194+
}
195+
}
196+
197+
func TestDeleteHost(t *testing.T) {
198+
var hostID = "d202964b5-8e73-46fd-b41b-a8e403f3c30b"
199+
200+
if err := fakeHostMgr.DeleteHost(hostID); err != nil {
201+
t.Error(err)
202+
return
203+
}
204+
}

0 commit comments

Comments
 (0)