Skip to content

Commit

Permalink
Add CRUD support for availability zone
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-v committed Nov 12, 2019
1 parent 0da2142 commit e13ab5d
Show file tree
Hide file tree
Showing 14 changed files with 779 additions and 40 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
*ZoneMgr

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),
ZoneMgr: NewZoneMgr(r, c.Endpoint, t),
}, nil
}

Expand Down
117 changes: 117 additions & 0 deletions client/zone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// 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"
)

// ZoneBuilder contains request body of handling a zone request.
// Currently it's assigned as the pointer of ZoneSpec struct, but it
// could be discussed if it's better to define an interface.
type ZoneBuilder *model.ZoneSpec

// NewZoneMgr
func NewZoneMgr(r Receiver, edp string, tenantId string) *ZoneMgr {
return &ZoneMgr{
Receiver: r,
Endpoint: edp,
TenantId: tenantId,
}
}

// ZoneMgr
type ZoneMgr struct {
Receiver
Endpoint string
TenantId string
}

// CreateZone
func (p *ZoneMgr) CreateZone(body ZoneBuilder) (*model.ZoneSpec, error) {
var res model.ZoneSpec
url := strings.Join([]string{
p.Endpoint,
urls.GenerateZoneURL(urls.Client, p.TenantId)}, "/")

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

return &res, nil
}

// GetZone
func (p *ZoneMgr) GetZone(zoneID string) (*model.ZoneSpec, error) {
var res model.ZoneSpec
url := strings.Join([]string{
p.Endpoint,
urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/")

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

return &res, nil
}

// UpdateZone ...
func (p *ZoneMgr) UpdateZone(zoneID string, body ZoneBuilder) (*model.ZoneSpec, error) {
var res model.ZoneSpec
url := strings.Join([]string{
p.Endpoint,
urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/")

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

return &res, nil
}

// ListZones
func (p *ZoneMgr) ListZones(args ...interface{}) ([]*model.ZoneSpec, error) {
var res []*model.ZoneSpec

url := strings.Join([]string{
p.Endpoint,
urls.GenerateZoneURL(urls.Client, p.TenantId)}, "/")

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

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

return res, nil
}

// DeleteZone
func (p *ZoneMgr) DeleteZone(zoneID string) error {
url := strings.Join([]string{
p.Endpoint,
urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/")

return p.Recv(url, "DELETE", nil, nil)
}
1 change: 1 addition & 0 deletions osdsctl/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func init() {
rootCommand.AddCommand(poolCommand)
rootCommand.AddCommand(profileCommand)
rootCommand.AddCommand(fileShareCommand)
rootCommand.AddCommand(zoneCommand)
flags := rootCommand.PersistentFlags()
flags.BoolVar(&Debug, "debug", false, "shows debugging output.")
}
Expand Down
163 changes: 163 additions & 0 deletions osdsctl/cli/zone.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// 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.

/*
This module implements a entry into the OpenSDS service.
*/

package cli

import (
"encoding/json"
"os"

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

var zoneCommand = &cobra.Command{
Use: "zone",
Short: "manage OpenSDS Availability Zone resources",
Run: zoneAction,
}

var zoneCreateCommand = &cobra.Command{
Use: "create <availability zone info>",
Short: "create a new availability zone resource",
Run: zoneCreateAction,
}

var zoneShowCommand = &cobra.Command{
Use: "show <availability zone id>",
Short: "show information of specified availability zone",
Run: zoneShowAction,
}

var zoneListCommand = &cobra.Command{
Use: "list",
Short: "get all availability zone resources",
Run: zoneListAction,
}

var zoneDeleteCommand = &cobra.Command{
Use: "delete <availability zone id>",
Short: "delete a specified availability zone resource",
Run: zoneDeleteAction,
}

var zoneUpdateCommand = &cobra.Command{
Use: "update <availability zone id> <availability zone info>",
Short: "update a specified zone resource",
Run: zoneUpdateAction,
}

var (
zoneLimit string
zoneOffset string
zoneSortDir string
zoneSortKey string
zoneId string
zoneName string
zoneDescription string
)

func init() {
zoneListCommand.Flags().StringVarP(&zoneLimit, "limit", "", "50", "the number of ertries displayed per page")
zoneListCommand.Flags().StringVarP(&zoneOffset, "offset", "", "0", "all requested data offsets")
zoneListCommand.Flags().StringVarP(&zoneSortDir, "sortDir", "", "desc", "the sort direction of all requested data. supports asc or desc(default)")
zoneListCommand.Flags().StringVarP(&zoneSortKey, "sortKey", "", "id", "the sort key of all requested data. supports id(default), name, description")
zoneListCommand.Flags().StringVarP(&zoneId, "id", "", "", "list availability zone by id")
zoneListCommand.Flags().StringVarP(&zoneName, "name", "", "", "list availability zone by name")
zoneListCommand.Flags().StringVarP(&zoneDescription, "description", "", "", "list availability zone by description")

zoneCommand.AddCommand(zoneCreateCommand)
zoneCommand.AddCommand(zoneShowCommand)
zoneCommand.AddCommand(zoneListCommand)
zoneCommand.AddCommand(zoneDeleteCommand)
zoneCommand.AddCommand(zoneUpdateCommand)
}

func zoneAction(cmd *cobra.Command, args []string) {
cmd.Usage()
os.Exit(1)
}

var zoneFormatters = FormatterList{}

func zoneCreateAction(cmd *cobra.Command, args []string) {
ArgsNumCheck(cmd, args, 1)
az := &model.ZoneSpec{}
if err := json.Unmarshal([]byte(args[0]), az); err != nil {
Errorln(err)
cmd.Usage()
os.Exit(1)
}

resp, err := client.CreateZone(az)
if err != nil {
Fatalln(HttpErrStrip(err))
}
keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description"}
PrintDict(resp, keys, zoneFormatters)
}

func zoneShowAction(cmd *cobra.Command, args []string) {
ArgsNumCheck(cmd, args, 1)
resp, err := client.GetZone(args[0])
if err != nil {
Fatalln(HttpErrStrip(err))
}
keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description"}
PrintDict(resp, keys, zoneFormatters)
}

func zoneListAction(cmd *cobra.Command, args []string) {
ArgsNumCheck(cmd, args, 0)
var opts = map[string]string{"limit": zoneLimit, "offset": zoneOffset, "sortDir": zoneSortDir,
"sortKey": zoneSortKey, "Id": zoneId,
"Name": zoneName, "Description": zoneDescription}

resp, err := client.ListZones(opts)
if err != nil {
Fatalln(HttpErrStrip(err))
}
keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description"}
PrintList(resp, keys, FormatterList{})
}

func zoneDeleteAction(cmd *cobra.Command, args []string) {
ArgsNumCheck(cmd, args, 1)
err := client.DeleteZone(args[0])
if err != nil {
Fatalln(HttpErrStrip(err))
}
}

func zoneUpdateAction(cmd *cobra.Command, args []string) {
ArgsNumCheck(cmd, args, 2)
az := &model.ZoneSpec{}

if err := json.Unmarshal([]byte(args[1]), az); err != nil {
Errorln(err)
cmd.Usage()
os.Exit(1)
}

resp, err := client.UpdateZone(args[0], az)
if err != nil {
Fatalln(HttpErrStrip(err))
}
keys := KeyList{"Id", "UpdatedAt", "Name", "Description"}
PrintDict(resp, keys, FormatterList{})
}
22 changes: 0 additions & 22 deletions pkg/api/controllers/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,6 @@ type PoolPortal struct {
BasePortal
}

func (p *PoolPortal) ListAvailabilityZones() {
if !policy.Authorize(p.Ctx, "availability_zone:list") {
return
}
azs, err := db.C.ListAvailabilityZones(c.GetContext(p.Ctx))
if err != nil {
errMsg := fmt.Sprintf("get AvailabilityZones for pools failed: %s", err.Error())
p.ErrorHandle(model.ErrorInternalServer, errMsg)
return
}

body, err := json.Marshal(azs)
if err != nil {
errMsg := fmt.Sprintf("marshal AvailabilityZones failed: %s", err.Error())
p.ErrorHandle(model.ErrorInternalServer, errMsg)
return
}

p.SuccessHandle(StatusOK, body)
return
}

func (p *PoolPortal) ListPools() {
if !policy.Authorize(p.Ctx, "pool:list") {
return
Expand Down
34 changes: 17 additions & 17 deletions pkg/api/controllers/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,26 +32,26 @@ import (
func init() {
var poolPortal PoolPortal
beego.Router("/v1beta/pools", &poolPortal, "get:ListPools")
beego.Router("/v1beta/availabilityZones", &poolPortal, "get:ListAvailabilityZones")
// beego.Router("/v1beta/availabilityZones", &poolPortal, "get:ListAvailabilityZones")
beego.Router("/v1beta/pools/:poolId", &poolPortal, "get:GetPool")
}

func TestListAvailabilityZones(t *testing.T) {

t.Run("Should return 200 if everything works well", func(t *testing.T) {
mockClient := new(dbtest.Client)
mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return(SampleAvailabilityZones, nil)
db.C = mockClient

r, _ := http.NewRequest("GET", "/v1beta/availabilityZones", nil)
w := httptest.NewRecorder()
beego.BeeApp.Handlers.ServeHTTP(w, r)
var output []string
json.Unmarshal(w.Body.Bytes(), &output)
assertTestResult(t, w.Code, 200)
assertTestResult(t, output, SampleAvailabilityZones)
})
}
// func TestListAvailabilityZones(t *testing.T) {

// t.Run("Should return 200 if everything works well", func(t *testing.T) {
// mockClient := new(dbtest.Client)
// mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return(SampleAvailabilityZones, nil)
// db.C = mockClient

// r, _ := http.NewRequest("GET", "/v1beta/availabilityZones", nil)
// w := httptest.NewRecorder()
// beego.BeeApp.Handlers.ServeHTTP(w, r)
// var output []string
// json.Unmarshal(w.Body.Bytes(), &output)
// assertTestResult(t, w.Code, 200)
// assertTestResult(t, output, SampleAvailabilityZones)
// })
// }

func TestListPools(t *testing.T) {

Expand Down
Loading

0 comments on commit e13ab5d

Please sign in to comment.