Skip to content

Commit

Permalink
Merge pull request #513 from opensds/development
Browse files Browse the repository at this point in the history
Merge development into master branch for publishing Bali milestone-1
  • Loading branch information
xing-yang committed Aug 7, 2018
2 parents 7ee7651 + 9405887 commit 64253fe
Show file tree
Hide file tree
Showing 12 changed files with 171 additions and 2 deletions.
5 changes: 3 additions & 2 deletions examples/policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@
"volume_group:list": "rule:admin_or_owner",
"volume_group:get": "rule:admin_or_owner",
"volume_group:update": "rule:admin_or_owner",
"volume_group:delete": "rule:admin_or_owner"
}
"volume_group:delete": "rule:admin_or_owner",
"availability_zone:list":""
}
19 changes: 19 additions & 0 deletions openapi-spec/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,25 @@ paths:
description: Forbidden
'500':
$ref: '#/responses/HTTPStatus500'
'/v1beta/{projectId}/availabilityZones':
parameters:
- $ref: '#/parameters/projectId'
get:
tags:
- Availability Zone
description: Lists availability zones.
responses:
'200':
description: OK
schema:
type: array
items:string
'401':
description: Unauthorized
'403':
description: Forbidden
'500':
$ref: '#/responses/HTTPStatus500'
'/v1beta/{projectId}/pools/{poolId}':
parameters:
- $ref: '#/parameters/projectId'
Expand Down
27 changes: 27 additions & 0 deletions pkg/api/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,33 @@ type PoolPortal struct {
BasePortal
}

func (this *PoolPortal) ListAvailabilityZones() {
if !policy.Authorize(this.Ctx, "availability_zone:list") {
return
}
azs, err := db.C.ListAvailabilityZones(c.GetContext(this.Ctx))
if err != nil {
reason := fmt.Sprintf("Get AvailabilityZones for pools failed: %s", err.Error())
this.Ctx.Output.SetStatus(model.ErrorBadRequest)
this.Ctx.Output.Body(model.ErrorBadRequestStatus(reason))
log.Error(reason)
return
}

body, err := json.Marshal(azs)
if err != nil {
reason := fmt.Sprintf("Marshal AvailabilityZones failed: %s", err.Error())
this.Ctx.Output.SetStatus(model.ErrorInternalServer)
this.Ctx.Output.Body(model.ErrorInternalServerStatus(reason))
log.Error(reason)
return
}

this.Ctx.Output.SetStatus(StatusOK)
this.Ctx.Output.Body(body)
return
}

func (this *PoolPortal) ListPools() {
if !policy.Authorize(this.Ctx, "pool:list") {
return
Expand Down
18 changes: 18 additions & 0 deletions pkg/api/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/http"
"net/http/httptest"
"reflect"
"strings"
"testing"

"github.com/astaxie/beego"
Expand All @@ -32,6 +33,7 @@ import (
func init() {
var poolPortal PoolPortal
beego.Router("/v1beta/pools", &poolPortal, "get:ListPools")
beego.Router("/v1beta/availabilityZones", &poolPortal, "get:ListAvailabilityZones")
beego.Router("/v1beta/pools/:poolId", &poolPortal, "get:GetPool")
}

Expand Down Expand Up @@ -66,6 +68,22 @@ var (
fakePools = []*model.StoragePoolSpec{fakePool}
)

func TestListAvailabilityZones(t *testing.T) {
mockClient := new(dbtest.MockClient)
mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return(fakePools, nil)
db.C = mockClient

r, _ := http.NewRequest("GET", "/v1beta/availabilityZones", nil)
w := httptest.NewRecorder()
beego.BeeApp.Handlers.ServeHTTP(w, r)

expectedZones := "unknow"
t.Log(w)
if !strings.Contains(string(w.Body.Bytes()), expectedZones) {
t.Errorf("Expected %v, actual %v", expectedZones, w.Body.Bytes())
}
}

func TestListPools(t *testing.T) {

mockClient := new(dbtest.MockClient)
Expand Down
1 change: 1 addition & 0 deletions pkg/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func Run(host string) {
// ListPools and GetPool are used for checking the status of backend pool, admin only
beego.NSRouter("/:tenantId/pools", &PoolPortal{}, "get:ListPools"),
beego.NSRouter("/:tenantId/pools/:poolId", &PoolPortal{}, "get:GetPool"),
beego.NSRouter("/:tenantId/availabilityZones", &PoolPortal{}, "get:ListAvailabilityZones"),

beego.NSNamespace("/:tenantId/block",

Expand Down
2 changes: 2 additions & 0 deletions pkg/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ type Client interface {

GetPool(ctx *c.Context, polID string) (*model.StoragePoolSpec, error)

ListAvailabilityZones(ctx *c.Context) ([]string, error)

ListPools(ctx *c.Context) ([]*model.StoragePoolSpec, error)

ListPoolsWithFilter(ctx *c.Context, m map[string][]string) ([]*model.StoragePoolSpec, error)
Expand Down
27 changes: 27 additions & 0 deletions pkg/db/drivers/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,33 @@ func (c *Client) GetPool(ctx *c.Context, polID string) (*model.StoragePoolSpec,
return pol, nil
}

//ListAvailabilityZones
func (c *Client) ListAvailabilityZones(ctx *c.Context) ([]string, error) {
dbReq := &Request{
Url: urls.GeneratePoolURL(urls.Etcd, ""),
}
dbRes := c.List(dbReq)
if dbRes.Status != "Success" {
log.Error("Failed to get AZ for pools in db:", dbRes.Error)
return nil, errors.New(dbRes.Error)
}
var azs = []string{}
if len(dbRes.Message) == 0 {
return azs, nil
}
for _, msg := range dbRes.Message {
var pol = &model.StoragePoolSpec{}
if err := json.Unmarshal([]byte(msg), pol); err != nil {
log.Error("When parsing pool in db:", dbRes.Error)
return nil, errors.New(dbRes.Error)
}
azs = append(azs, pol.AvailabilityZone)
}
//remove redundant AZ
azs = utils.RvRepElement(azs)
return azs, nil
}

// ListPools
func (c *Client) ListPools(ctx *c.Context) ([]*model.StoragePoolSpec, error) {
dbReq := &Request{
Expand Down
11 changes: 11 additions & 0 deletions pkg/db/drivers/etcd/etcd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,17 @@ func TestListDocks(t *testing.T) {
}
}

func TestListAvailabilityZones(t *testing.T) {
azs, err := fc.ListAvailabilityZones(c.NewAdminContext())
if err != nil {
t.Error("List pools failed:", err)
}
expected := SamplePools[0].AvailabilityZone
if !reflect.DeepEqual(azs[0], expected) {
t.Errorf("Expected %+v, got %+v\n", expected, azs[0])
}
}

func TestListPools(t *testing.T) {
m := map[string][]string{
"offset": []string{"0"},
Expand Down
18 changes: 18 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ import (
log "github.com/golang/glog"
)

//remove redundant elements
func RvRepElement(arr []string) []string {
result := []string{}
for i := 0; i < len(arr); i++ {
flag := true
for j := range result {
if arr[i] == result[j] {
flag = false
break
}
}
if flag == true {
result = append(result, arr[i])
}
}
return result
}

func Contained(obj, target interface{}) bool {
targetValue := reflect.ValueOf(target)
switch reflect.TypeOf(target).Kind() {
Expand Down
10 changes: 10 additions & 0 deletions pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ import (
"github.com/opensds/opensds/pkg/model"
)

func TestRvRepElement(t *testing.T) {
var strs = []string{"default", "default"}
str := RvRepElement(strs)
res := str[0]
var expect = "default"
if len(str) != 1 || res != expect {
t.Errorf("%v remove redundant elements fail,expect:%v,result:%v\n", str, expect, res)
}
}

func TestContained(t *testing.T) {
var targets = []interface{}{
[]interface{}{"key01", 123, true},
Expand Down
10 changes: 10 additions & 0 deletions testutils/db/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ func (fc *FakeDbClient) ListDocks(ctx *c.Context) ([]*model.DockSpec, error) {
return dcks, nil
}

//ListAvailabilityZones
func (fc *FakeDbClient) ListAvailabilityZones(ctx *c.Context) ([]string, error) {
var azs []string
for i := range SamplePools {
az := SamplePools[i].AvailabilityZone
azs = append(azs, az)
}
return azs, nil
}

// UpdateDock
func (fc *FakeDbClient) UpdateDock(ctx *c.Context, dckID, name, desp string) (*model.DockSpec, error) {
return nil, nil
Expand Down
25 changes: 25 additions & 0 deletions testutils/db/testing/mock_db.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 64253fe

Please sign in to comment.