From 7856ef6d27bfbd3f310da2a0acacadfbde2bd993 Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Tue, 12 Nov 2019 15:32:44 +0530 Subject: [PATCH 1/7] Add CRUD support for availability zone --- client/client.go | 2 + client/zone.go | 117 +++++++++++++++++ osdsctl/cli/cli.go | 1 + osdsctl/cli/zone.go | 163 ++++++++++++++++++++++++ pkg/api/controllers/pool.go | 22 ---- pkg/api/controllers/pool_test.go | 34 ++--- pkg/api/controllers/zone.go | 212 +++++++++++++++++++++++++++++++ pkg/api/routers/router.go | 3 +- pkg/db/db.go | 12 ++ pkg/db/drivers/etcd/etcd.go | 136 ++++++++++++++++++++ pkg/model/zone.go | 55 ++++++++ pkg/utils/urls/urls.go | 4 + testutils/db/fake.go | 29 +++++ testutils/db/testing/client.go | 29 +++++ 14 files changed, 779 insertions(+), 40 deletions(-) create mode 100644 client/zone.go create mode 100644 osdsctl/cli/zone.go create mode 100644 pkg/api/controllers/zone.go create mode 100644 pkg/model/zone.go diff --git a/client/client.go b/client/client.go index 5173586d9..094f9eb37 100755 --- a/client/client.go +++ b/client/client.go @@ -43,6 +43,7 @@ type Client struct { *ReplicationMgr *FileShareMgr *HostMgr + *ZoneMgr cfg *Config } @@ -100,6 +101,7 @@ func NewClient(c *Config) (*Client, error) { ReplicationMgr: NewReplicationMgr(r, c.Endpoint, t), FileShareMgr: NewFileShareMgr(r, c.Endpoint, t), HostMgr: NewHostMgr(r, c.Endpoint, t), + ZoneMgr: NewZoneMgr(r, c.Endpoint, t), }, nil } diff --git a/client/zone.go b/client/zone.go new file mode 100644 index 000000000..d21cb5b70 --- /dev/null +++ b/client/zone.go @@ -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) +} diff --git a/osdsctl/cli/cli.go b/osdsctl/cli/cli.go index b28ea68f6..f840211c9 100644 --- a/osdsctl/cli/cli.go +++ b/osdsctl/cli/cli.go @@ -50,6 +50,7 @@ func init() { rootCommand.AddCommand(profileCommand) rootCommand.AddCommand(fileShareCommand) rootCommand.AddCommand(hostCommand) + rootCommand.AddCommand(zoneCommand) flags := rootCommand.PersistentFlags() flags.BoolVar(&Debug, "debug", false, "shows debugging output.") } diff --git a/osdsctl/cli/zone.go b/osdsctl/cli/zone.go new file mode 100644 index 000000000..ffbdb03f2 --- /dev/null +++ b/osdsctl/cli/zone.go @@ -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 ", + Short: "create a new availability zone resource", + Run: zoneCreateAction, +} + +var zoneShowCommand = &cobra.Command{ + Use: "show ", + 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 ", + Short: "delete a specified availability zone resource", + Run: zoneDeleteAction, +} + +var zoneUpdateCommand = &cobra.Command{ + Use: "update ", + 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{}) +} \ No newline at end of file diff --git a/pkg/api/controllers/pool.go b/pkg/api/controllers/pool.go index e764f0cbf..73b1922d4 100755 --- a/pkg/api/controllers/pool.go +++ b/pkg/api/controllers/pool.go @@ -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 diff --git a/pkg/api/controllers/pool_test.go b/pkg/api/controllers/pool_test.go index 6f2632178..f4c934ad3 100755 --- a/pkg/api/controllers/pool_test.go +++ b/pkg/api/controllers/pool_test.go @@ -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) { diff --git a/pkg/api/controllers/zone.go b/pkg/api/controllers/zone.go new file mode 100644 index 000000000..aa5391908 --- /dev/null +++ b/pkg/api/controllers/zone.go @@ -0,0 +1,212 @@ +// 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 northbound service. + +*/ + +package controllers + +import ( + "encoding/json" + "fmt" + // "strings" + + // log "github.com/golang/glog" + "github.com/opensds/opensds/pkg/api/policy" + c "github.com/opensds/opensds/pkg/context" + "github.com/opensds/opensds/pkg/db" + "github.com/opensds/opensds/pkg/model" + // "github.com/opensds/opensds/pkg/utils/constants" +) + +type ZonePortal struct { + BasePortal +} + +func (p *ZonePortal) ListAvailabilityZones() { + if !policy.Authorize(p.Ctx, "availability_zone:list") { + return + } + azs, err := db.C.ListZones(c.GetContext(p.Ctx)) + if err != nil { + errMsg := fmt.Sprintf("get AvailabilityZones 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 *ZonePortal) CreateZone() { + if !policy.Authorize(p.Ctx, "zone:create") { + return + } + + var zone = model.ZoneSpec{ + BaseModel: &model.BaseModel{}, + } + + // Unmarshal the request body + if err := json.NewDecoder(p.Ctx.Request.Body).Decode(&zone); err != nil { + errMsg := fmt.Sprintf("parse zone request body failed: %v", err) + p.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + // Call db api module to handle create zone request. + result, err := db.C.CreateZone(c.GetContext(p.Ctx), &zone) + if err != nil { + errMsg := fmt.Sprintf("create zone failed: %v", err) + p.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + // Marshal the result. + body, err := json.Marshal(result) + if err != nil { + errMsg := fmt.Sprintf("marshal zone created result failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + p.SuccessHandle(StatusOK, body) + return +} + +func (p *ZonePortal) ListZones() { + if !policy.Authorize(p.Ctx, "zone:list") { + return + } + + m, err := p.GetParameters() + if err != nil { + errMsg := fmt.Sprintf("list zones failed: %v", err) + p.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + result, err := db.C.ListZonesWithFilter(c.GetContext(p.Ctx), m) + if err != nil { + errMsg := fmt.Sprintf("list zones failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + // Marshal the result. + body, err := json.Marshal(result) + if err != nil { + errMsg := fmt.Sprintf("marshal zones listed result failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + p.SuccessHandle(StatusOK, body) + return +} + +func (p *ZonePortal) GetZone() { + if !policy.Authorize(p.Ctx, "zone:get") { + return + } + id := p.Ctx.Input.Param(":zoneId") + + result, err := db.C.GetZone(c.GetContext(p.Ctx), id) + if err != nil { + errMsg := fmt.Sprintf("zone %s not found: %v", id, err) + p.ErrorHandle(model.ErrorNotFound, errMsg) + return + } + + // Marshal the result. + body, err := json.Marshal(result) + if err != nil { + errMsg := fmt.Sprintf("marshal zone got result failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + p.SuccessHandle(StatusOK, body) + return +} + +func (p *ZonePortal) UpdateZone() { + + if !policy.Authorize(p.Ctx, "zone:update") { + return + } + + var zone = model.ZoneSpec{ + BaseModel: &model.BaseModel{}, + } + id := p.Ctx.Input.Param(":zoneId") + + if err := json.NewDecoder(p.Ctx.Request.Body).Decode(&zone); err != nil { + errMsg := fmt.Sprintf("parse zone request body failed: %v", err) + p.ErrorHandle(model.ErrorBadRequest, errMsg) + return + } + + result, err := db.C.UpdateZone(c.GetContext(p.Ctx), id, &zone) + if err != nil { + errMsg := fmt.Sprintf("update zones failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + // Marshal the result. + body, err := json.Marshal(result) + if err != nil { + errMsg := fmt.Sprintf("marshal zone updated result failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + p.SuccessHandle(StatusOK, body) + return +} + +func (p *ZonePortal) DeleteZone() { + + if !policy.Authorize(p.Ctx, "zone:delete") { + return + } + id := p.Ctx.Input.Param(":zoneId") + ctx := c.GetContext(p.Ctx) + zone, err := db.C.GetZone(ctx, id) + if err != nil { + errMsg := fmt.Sprintf("zone %s not found: %v", id, err) + p.ErrorHandle(model.ErrorNotFound, errMsg) + return + } + + err = db.C.DeleteZone(ctx, zone.Id) + if err != nil { + errMsg := fmt.Sprintf("delete zones failed: %v", err) + p.ErrorHandle(model.ErrorInternalServer, errMsg) + return + } + + p.SuccessHandle(StatusOK, nil) + return +} diff --git a/pkg/api/routers/router.go b/pkg/api/routers/router.go index d4a79177e..66f214886 100755 --- a/pkg/api/routers/router.go +++ b/pkg/api/routers/router.go @@ -60,7 +60,8 @@ func init() { // ListPools and GetPool are used for checking the status of backend pool, admin only beego.NSRouter("/:tenantId/pools", &controllers.PoolPortal{}, "get:ListPools"), beego.NSRouter("/:tenantId/pools/:poolId", &controllers.PoolPortal{}, "get:GetPool"), - beego.NSRouter("/:tenantId/availabilityZones", &controllers.PoolPortal{}, "get:ListAvailabilityZones"), + beego.NSRouter("/:tenantId/availabilityZones", &controllers.ZonePortal{}, "get:ListAvailabilityZones;post:CreateZone"), + beego.NSRouter("/:tenantId/availabilityZones/:zoneId", &controllers.ZonePortal{}, "get:GetZone;put:UpdateZone;delete:DeleteZone"), ) beego.AddNamespace(ns) diff --git a/pkg/db/db.go b/pkg/db/db.go index e159563c5..fb80c2ca1 100755 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -125,6 +125,18 @@ type Client interface { DeletePool(ctx *c.Context, polID string) error + GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) + + CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) + + ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) + + ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) + + UpdateZone(ctx *c.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) + + DeleteZone(ctx *c.Context, zoneID string) error + CreateProfile(ctx *c.Context, prf *model.ProfileSpec) (*model.ProfileSpec, error) GetProfile(ctx *c.Context, prfID string) (*model.ProfileSpec, error) diff --git a/pkg/db/drivers/etcd/etcd.go b/pkg/db/drivers/etcd/etcd.go index 2e3d19925..750b41e9e 100644 --- a/pkg/db/drivers/etcd/etcd.go +++ b/pkg/db/drivers/etcd/etcd.go @@ -1359,6 +1359,142 @@ func (c *Client) ListAvailabilityZones(ctx *c.Context) ([]string, error) { return azs, nil } +// GetZone +func (c *Client) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) { + dbReq := &Request{ + Url: urls.GenerateZoneURL(urls.Etcd, "", zoneID), + } + dbRes := c.Get(dbReq) + if dbRes.Status != "Success" { + log.Error("When get zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + + var z = &model.ZoneSpec{} + if err := json.Unmarshal([]byte(dbRes.Message[0]), z); err != nil { + log.Error("When parsing zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + return z, nil +} + +// CreateZone +func (c *Client) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + if zone.Id == "" { + zone.Id = uuid.NewV4().String() + } + if zone.CreatedAt == "" { + zone.CreatedAt = time.Now().Format(constants.TimeFormat) + } + + // zone name must be unique. + // if _, err := c.getZoneByName(ctx, zone.Name); err == nil { + // return nil, fmt.Errorf("the zone name '%s' already exists", zone.Name) + // } + + zoneBody, err := json.Marshal(zone) + if err != nil { + return nil, err + } + + dbReq := &Request{ + Url: urls.GenerateZoneURL(urls.Etcd, "", zone.Id), + Content: string(zoneBody), + } + dbRes := c.Create(dbReq) + if dbRes.Status != "Success" { + log.Error("When create zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + + return zone, nil +} + +// UpdateZone +func (c *Client) UpdateZone(ctx *c.Context, zoneID string, input *model.ZoneSpec) (*model.ZoneSpec, error) { + z, err := c.GetZone(ctx, zoneID) + if err != nil { + return nil, err + } + if name := input.Name; name != "" { + z.Name = name + } + if desc := input.Description; desc != "" { + z.Description = desc + } + z.UpdatedAt = time.Now().Format(constants.TimeFormat) + + zBody, err := json.Marshal(z) + if err != nil { + return nil, err + } + + dbReq := &Request{ + Url: urls.GenerateZoneURL(urls.Etcd, "", zoneID), + NewContent: string(zBody), + } + dbRes := c.Update(dbReq) + if dbRes.Status != "Success" { + log.Error("When update zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + return z, nil +} + +// DeleteZone +func (c *Client) DeleteZone(ctx *c.Context, zoneID string) error { + dbReq := &Request{ + Url: urls.GenerateZoneURL(urls.Etcd, "", zoneID), + } + dbRes := c.Delete(dbReq) + if dbRes.Status != "Success" { + log.Error("When delete profile in db:", dbRes.Error) + return errors.New(dbRes.Error) + } + return nil +} + +//ListZonesWithFilter +func (c *Client) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) { + zones, err := c.ListZones(ctx) + if err != nil { + log.Error("List zones failed: ", err.Error()) + return nil, err + } + + // z := c.SelectZones(m, zones) + // p := c.ParameterFilter(m, len(z), []string{"ID", "NAME", "STATUS", "AVAILABILITYZONE", "DOCKID", "DESCRIPTION"}) + // return c.SortZones(z, p)[p.beginIdx:p.endIdx], nil + + return zones, nil +} + +//ListZones +func (c *Client) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { + dbReq := &Request{ + Url: urls.GenerateZoneURL(urls.Etcd, ""), + } + dbRes := c.List(dbReq) + if dbRes.Status != "Success" { + log.Error("Failed to get zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + var azs = []*model.ZoneSpec{} + if len(dbRes.Message) == 0 { + return azs, nil + } + for _, msg := range dbRes.Message { + var az = &model.ZoneSpec{} + if err := json.Unmarshal([]byte(msg), az); err != nil { + log.Error("When parsing zone in db:", dbRes.Error) + return nil, errors.New(dbRes.Error) + } + azs = append(azs, az) + } + + return azs, nil +} + // ListPools func (c *Client) ListPools(ctx *c.Context) ([]*model.StoragePoolSpec, error) { dbReq := &Request{ diff --git a/pkg/model/zone.go b/pkg/model/zone.go new file mode 100644 index 000000000..6c87e034b --- /dev/null +++ b/pkg/model/zone.go @@ -0,0 +1,55 @@ +// 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 the common data structure. + +*/ + +package model + +import ( + "encoding/json" + + "github.com/golang/glog" +) + +// An OpenSDS zone is identified by a unique name and ID. +type ZoneSpec struct { + *BaseModel + + // The name of the zone. + Name string `json:"name,omitempty"` + + // The description of the zone. + // +optional + Description string `json:"description,omitempty"` +} + +func NewZoneFromJson(s string) *ZoneSpec { + p := &ZoneSpec{} + err := json.Unmarshal([]byte(s), p) + if err != nil { + glog.Errorf("Unmarshal json to ZoneSpec failed, %v", err) + } + return p +} + +func (p *ZoneSpec) ToJson() string { + b, err := json.Marshal(p) + if err != nil { + glog.Errorf("ZoneSpec convert to json failed, %v", err) + } + return string(b) +} diff --git a/pkg/utils/urls/urls.go b/pkg/utils/urls/urls.go index d2a96d9d7..21e55861f 100644 --- a/pkg/utils/urls/urls.go +++ b/pkg/utils/urls/urls.go @@ -49,6 +49,10 @@ func GeneratePoolURL(urlType int, tenantId string, in ...string) string { return generateURL("pools", urlType, tenantId, in...) } +func GenerateZoneURL(urlType int, tenantId string, in ...string) string { + return generateURL("availabilityZones", urlType, tenantId, in...) +} + func GenerateProfileURL(urlType int, tenantId string, in ...string) string { return generateURL("profiles", urlType, tenantId, in...) } diff --git a/testutils/db/fake.go b/testutils/db/fake.go index 616435d38..1a51e0931 100755 --- a/testutils/db/fake.go +++ b/testutils/db/fake.go @@ -230,6 +230,35 @@ func (fc *FakeDbClient) ListAvailabilityZones(ctx *c.Context) ([]string, error) return azs, nil } +// GetZone +func (fc *FakeDbClient) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) { + return nil, nil +} + +// CreateZone +func (fc *FakeDbClient) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + return nil, nil +} + +// UpdateZone +func (fc *FakeDbClient) UpdateZone(ctx *c.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + return nil, nil +} + +// DeleteZone +func (fc *FakeDbClient) DeleteZone(ctx *c.Context, zoneID string) error { + return nil +} + +// ListZonesWithFilter +func (fc *FakeDbClient) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) { + return nil, nil +} + +func (fc *FakeDbClient) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { + return nil, nil +} + // UpdateDock func (fc *FakeDbClient) UpdateDock(ctx *c.Context, dckID, name, desp string) (*model.DockSpec, error) { return nil, nil diff --git a/testutils/db/testing/client.go b/testutils/db/testing/client.go index f786c9205..28f5e4f96 100644 --- a/testutils/db/testing/client.go +++ b/testutils/db/testing/client.go @@ -916,6 +916,35 @@ func (_m *Client) ListAvailabilityZones(ctx *context.Context) ([]string, error) return r0, r1 } +// GetZone +func (_m *Client) GetZone(ctx *context.Context, zoneID string) (*model.ZoneSpec, error) { + return nil, nil +} + +// CreateZone +func (_m *Client) CreateZone(ctx *context.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + return nil, nil +} + +// UpdateZone +func (_m *Client) UpdateZone(ctx *context.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + return nil, nil +} + +// DeleteZone +func (_m *Client) DeleteZone(ctx *context.Context, zoneID string) error { + return nil +} + +// ListZonesWithFilter +func (_m *Client) ListZonesWithFilter(ctx *context.Context, m map[string][]string) ([]*model.ZoneSpec, error) { + return nil, nil +} + +func (f_m *Client) ListZones(ctx *context.Context) ([]*model.ZoneSpec, error) { + return nil, nil +} + // ListCustomProperties provides a mock function with given fields: ctx, prfID func (_m *Client) ListCustomProperties(ctx *context.Context, prfID string) (*model.CustomPropertiesSpec, error) { ret := _m.Called(ctx, prfID) From a72b77e11acb5ff8051ca5403555a0e002f2b8ea Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Wed, 13 Nov 2019 10:00:03 +0530 Subject: [PATCH 2/7] Add testcases for zone client --- client/fake.go | 65 ++++++++++++++++++ client/zone_test.go | 129 +++++++++++++++++++++++++++++++++++ testutils/collection/data.go | 20 ++++++ 3 files changed, 214 insertions(+) create mode 100644 client/zone_test.go diff --git a/client/fake.go b/client/fake.go index 18d3397be..a95d09748 100644 --- a/client/fake.go +++ b/client/fake.go @@ -63,8 +63,13 @@ func NewFakeClient(config *Config) *Client { Receiver: NewFakeFileShareReceiver(), Endpoint: config.Endpoint, }, +<<<<<<< 211553282aff0b5c8d3f9d7faec703fbb9d34cdb HostMgr: &HostMgr{ Receiver: NewFakeHostReceiver(), +======= + ZoneMgr: &ZoneMgr{ + Receiver: NewFakeZoneReceiver(), +>>>>>>> Add testcases for zone client Endpoint: config.Endpoint, }, } @@ -488,3 +493,63 @@ func (*fakeHostReceiver) Recv( return nil } + +func NewFakeZoneReceiver() Receiver { + return &fakeZoneReceiver{} +} + +type fakeZoneReceiver struct{} + +func (*fakeZoneReceiver) Recv( + string, + method string, + in interface{}, + out interface{}, +) error { + switch strings.ToUpper(method) { + case "POST": + switch out.(type) { + case *model.ZoneSpec: + if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + return err + } + break + default: + return errors.New("output format not supported") + } + break + case "GET": + switch out.(type) { + case *model.ZoneSpec: + if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + return err + } + break + case *[]*model.ZoneSpec: + if err := json.Unmarshal([]byte(ByteZones), out); err != nil { + return err + } + break + default: + return errors.New("output format not supported") + } + break + case "PUT": + switch out.(type) { + case *model.ZoneSpec: + if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + return err + } + break + default: + return errors.New("output format not supported") + } + break + case "DELETE": + break + default: + return errors.New("inputed method format not supported") + } + + return nil +} diff --git a/client/zone_test.go b/client/zone_test.go new file mode 100644 index 000000000..00f5c3a96 --- /dev/null +++ b/client/zone_test.go @@ -0,0 +1,129 @@ +// 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 fzn = &ZoneMgr{ + Receiver: NewFakeZoneReceiver(), +} + +func TestCreateZone(t *testing.T) { + expected := &model.ZoneSpec{ + BaseModel: &model.BaseModel{ + Id: "1106b972-66ef-11e7-b172-db03f3689c9c", + }, + Name: "default", + Description: "default zone", + } + + zn, err := fzn.CreateZone(&model.ZoneSpec{}) + if err != nil { + t.Error(err) + return + } + + if !reflect.DeepEqual(zn, expected) { + t.Errorf("Expected %v, got %v", expected, zn) + return + } +} + +func TestGetZone(t *testing.T) { + var znID = "1106b972-66ef-11e7-b172-db03f3689c9c" + expected := &model.ZoneSpec{ + BaseModel: &model.BaseModel{ + Id: "1106b972-66ef-11e7-b172-db03f3689c9c", + }, + Name: "default", + Description: "default zone", + } + + zn, err := fzn.GetZone(znID) + if err != nil { + t.Error(err) + return + } + + if !reflect.DeepEqual(zn, expected) { + t.Errorf("Expected %v, got %v", expected, zn) + return + } +} + +func TestListZones(t *testing.T) { + expected := []*model.ZoneSpec{ + { + BaseModel: &model.BaseModel{ + Id: "1106b972-66ef-11e7-b172-db03f3689c9c", + }, + Name: "default", + Description: "default zone", + }, + { + BaseModel: &model.BaseModel{ + Id: "2f9c0a04-66ef-11e7-ade2-43158893e017", + }, + Name: "test", + Description: "test zone", + }, + } + + zns, err := fzn.ListZones() + if err != nil { + t.Error(err) + return + } + + if !reflect.DeepEqual(zns, expected) { + t.Errorf("Expected %v, got %v", expected[1], zns[1]) + return + } +} + +func TestUpdateZone(t *testing.T) { + expected := &model.ZoneSpec{ + BaseModel: &model.BaseModel{ + Id: "1106b972-66ef-11e7-b172-db03f3689c9c", + }, + Name: "default", + Description: "default zone", + } + + zn, err := fzn.UpdateZone("1106b972-66ef-11e7-b172-db03f3689c9c", &model.ZoneSpec{}) + if err != nil { + t.Error(err) + return + } + + if !reflect.DeepEqual(zn, expected) { + t.Errorf("Expected %v, got %v", expected, zn) + return + } +} + +func TestDeleteZone(t *testing.T) { + var znID = "1106b972-66ef-11e7-b172-db03f3689c9c" + + if err := fzn.DeleteZone(znID); err != nil { + t.Error(err) + return + } +} diff --git a/testutils/collection/data.go b/testutils/collection/data.go index 352d8efba..47a69b891 100644 --- a/testutils/collection/data.go +++ b/testutils/collection/data.go @@ -999,6 +999,26 @@ var ( ] } ]` + + ByteZone = `{ + "id": "1106b972-66ef-11e7-b172-db03f3689c9c", + "name": "default", + "description": "default zone" + }` + + ByteZones = `[ + { + "id": "1106b972-66ef-11e7-b172-db03f3689c9c", + "name": "default", + "description": "default zone" + }, + { + "id": "2f9c0a04-66ef-11e7-ade2-43158893e017", + "name": "test", + "description": "test zone" + } + ]` + ) // The StringSlice*** variable here is designed for unit test in etcd package. From 42dd30172b0b9d62815c6d2e06c9efa287288b55 Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Wed, 13 Nov 2019 11:41:05 +0530 Subject: [PATCH 3/7] Add testcases for zone controller --- pkg/api/controllers/zone_test.go | 244 +++++++++++++++++++++++++++++++ testutils/collection/data.go | 17 +++ testutils/db/testing/client.go | 158 ++++++++++++++++---- 3 files changed, 390 insertions(+), 29 deletions(-) create mode 100644 pkg/api/controllers/zone_test.go diff --git a/pkg/api/controllers/zone_test.go b/pkg/api/controllers/zone_test.go new file mode 100644 index 000000000..e2df9e163 --- /dev/null +++ b/pkg/api/controllers/zone_test.go @@ -0,0 +1,244 @@ +// 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 controllers + +import ( + "bytes" + "encoding/json" + "errors" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/astaxie/beego" + "github.com/astaxie/beego/context" + c "github.com/opensds/opensds/pkg/context" + "github.com/opensds/opensds/pkg/db" + "github.com/opensds/opensds/pkg/model" + . "github.com/opensds/opensds/testutils/collection" + dbtest "github.com/opensds/opensds/testutils/db/testing" +) + +func init() { + var zonePortal ZonePortal + beego.Router("/v1beta/availabilityZones", &zonePortal, "post:CreateZone;get:ListZones") + beego.Router("/v1beta/availabilityZones/:zoneId", &zonePortal, "get:GetZone;put:UpdateZone;delete:DeleteZone") +} + +//////////////////////////////////////////////////////////////////////////////// +// Tests for zone // +//////////////////////////////////////////////////////////////////////////////// + +func TestCreateZone(t *testing.T) { + var fakeBody = `{ + "name": "default", + "description": "default zone" + }` + + t.Run("Should return 200 if everything works well", func(t *testing.T) { + mockClient := new(dbtest.Client) + mockClient.On("CreateZone", c.NewAdminContext(), &model.ZoneSpec{ + BaseModel: &model.BaseModel{}, + Name: "default", + Description: "default zone", + }).Return(&SampleZones[1], nil) + db.C = mockClient + + r, _ := http.NewRequest("POST", "/v1beta/availabilityZones", strings.NewReader(fakeBody)) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + var output model.ZoneSpec + json.Unmarshal(w.Body.Bytes(), &output) + assertTestResult(t, w.Code, 200) + assertTestResult(t, &output, &SampleZones[1]) + }) +} + +func TestUpdateZone(t *testing.T) { + var jsonStr = []byte(`{ + "id": "2f9c0a04-66ef-11e7-ade2-43158893e017", + "name": "test", + "description": "test zone" + }`) + var expectedJson = []byte(`{ + "id": "2f9c0a04-66ef-11e7-ade2-43158893e017", + "name": "test", + "description": "test zone" + }`) + var expected model.ZoneSpec + json.Unmarshal(expectedJson, &expected) + + t.Run("Should return 200 if everything works well", func(t *testing.T) { + zone := model.ZoneSpec{BaseModel: &model.BaseModel{}} + json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&zone) + mockClient := new(dbtest.Client) + mockClient.On("UpdateZone", c.NewAdminContext(), zone.Id, &zone). + Return(&expected, nil) + db.C = mockClient + + r, _ := http.NewRequest("PUT", "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", bytes.NewBuffer(jsonStr)) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + var output model.ZoneSpec + json.Unmarshal(w.Body.Bytes(), &output) + assertTestResult(t, w.Code, 200) + assertTestResult(t, &output, &expected) + }) + + t.Run("Should return 500 if update zone with bad request", func(t *testing.T) { + zone := model.ZoneSpec{BaseModel: &model.BaseModel{}} + json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&zone) + mockClient := new(dbtest.Client) + mockClient.On("UpdateZone", c.NewAdminContext(), zone.Id, &zone). + Return(nil, errors.New("db error")) + db.C = mockClient + + r, _ := http.NewRequest("PUT", "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", bytes.NewBuffer(jsonStr)) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + assertTestResult(t, w.Code, 500) + }) +} + +func TestListZones(t *testing.T) { + + t.Run("Should return 200 if everything works well", func(t *testing.T) { + var sampleZones = []*model.ZoneSpec{&SampleZones[1]} + mockClient := new(dbtest.Client) + m := map[string][]string{ + "offset": {"0"}, + "limit": {"1"}, + "sortDir": {"asc"}, + "sortKey": {"name"}, + } + mockClient.On("ListZonesWithFilter", c.NewAdminContext(), m).Return( + sampleZones, nil) + db.C = mockClient + + r, _ := http.NewRequest("GET", "/v1beta/availabilityZones?offset=0&limit=1&sortDir=asc&sortKey=name", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + var output []*model.ZoneSpec + json.Unmarshal(w.Body.Bytes(), &output) + assertTestResult(t, w.Code, 200) + assertTestResult(t, output, sampleZones) + }) + + t.Run("Should return 500 if list zones with bad request", func(t *testing.T) { + mockClient := new(dbtest.Client) + m := map[string][]string{ + "offset": {"0"}, + "limit": {"1"}, + "sortDir": {"asc"}, + "sortKey": {"name"}, + } + mockClient.On("ListZonesWithFilter", c.NewAdminContext(), m).Return(nil, errors.New("db error")) + db.C = mockClient + + r, _ := http.NewRequest("GET", "/v1beta/availabilityZones?offset=0&limit=1&sortDir=asc&sortKey=name", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + assertTestResult(t, w.Code, 500) + }) +} + +func TestGetZone(t *testing.T) { + + t.Run("Should return 200 if everything works well", func(t *testing.T) { + mockClient := new(dbtest.Client) + mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017"). + Return(&SampleZones[1], nil) + db.C = mockClient + + r, _ := http.NewRequest("GET", "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + var output model.ZoneSpec + json.Unmarshal(w.Body.Bytes(), &output) + assertTestResult(t, w.Code, 200) + assertTestResult(t, &output, &SampleZones[1]) + }) + + t.Run("Should return 404 if get zone with bad request", func(t *testing.T) { + mockClient := new(dbtest.Client) + mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + nil, errors.New("db error")) + db.C = mockClient + + r, _ := http.NewRequest("GET", + "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + assertTestResult(t, w.Code, 404) + }) +} + +func TestDeleteZone(t *testing.T) { + + t.Run("Should return 200 if everything works well", func(t *testing.T) { + mockClient := new(dbtest.Client) + mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + &SampleZones[1], nil) + mockClient.On("DeleteZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return(nil) + db.C = mockClient + + r, _ := http.NewRequest("DELETE", + "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + assertTestResult(t, w.Code, 200) + }) + + t.Run("Should return 404 if delete zone with bad request", func(t *testing.T) { + mockClient := new(dbtest.Client) + mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + nil, errors.New("Invalid resource uuid")) + db.C = mockClient + + r, _ := http.NewRequest("DELETE", + "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", nil) + w := httptest.NewRecorder() + beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) { + httpCtx.Input.SetData("context", c.NewAdminContext()) + }) + beego.BeeApp.Handlers.ServeHTTP(w, r) + assertTestResult(t, w.Code, 404) + }) +} \ No newline at end of file diff --git a/testutils/collection/data.go b/testutils/collection/data.go index 47a69b891..db58d8e78 100644 --- a/testutils/collection/data.go +++ b/testutils/collection/data.go @@ -223,6 +223,23 @@ var ( SampleAvailabilityZones = []string{"default"} + SampleZones = []model.ZoneSpec{ + { + BaseModel: &model.BaseModel{ + Id: "1106b972-66ef-11e7-b172-db03f3689c9c", + }, + Name: "default", + Description: "default zone", + }, + { + BaseModel: &model.BaseModel{ + Id: "2f9c0a04-66ef-11e7-ade2-43158893e017", + }, + Name: "test", + Description: "test zone", + }, + } + SampleFileShares = []model.FileShareSpec{ { BaseModel: &model.BaseModel{ diff --git a/testutils/db/testing/client.go b/testutils/db/testing/client.go index 28f5e4f96..30eee50fa 100644 --- a/testutils/db/testing/client.go +++ b/testutils/db/testing/client.go @@ -311,6 +311,29 @@ func (_m *Client) CreateVolumeSnapshot(ctx *context.Context, vs *model.VolumeSna return r0, r1 } +// CreateZone +func (_m *Client) CreateZone(ctx *context.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { + ret := _m.Called(ctx, zone) + + var r0 *model.ZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, *model.ZoneSpec) *model.ZoneSpec); ok { + r0 = rf(ctx, zone) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.ZoneSpec) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*context.Context, *model.ZoneSpec) error); ok { + r1 = rf(ctx, zone) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // DeleteDock provides a mock function with given fields: ctx, dckID func (_m *Client) DeleteDock(ctx *context.Context, dckID string) error { ret := _m.Called(ctx, dckID) @@ -479,6 +502,20 @@ func (_m *Client) DeleteVolumeSnapshot(ctx *context.Context, snapshotID string) return r0 } +// DeleteZone +func (_m *Client) DeleteZone(ctx *context.Context, zoneID string) error { + ret := _m.Called(ctx, zoneID) + + var r0 error + if rf, ok := ret.Get(0).(func(*context.Context, string) error); ok { + r0 = rf(ctx, zoneID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // ExtendVolume provides a mock function with given fields: ctx, vol func (_m *Client) ExtendVolume(ctx *context.Context, vol *model.VolumeSpec) (*model.VolumeSpec, error) { ret := _m.Called(ctx, vol) @@ -870,6 +907,29 @@ func (_m *Client) GetVolumeSnapshot(ctx *context.Context, snapshotID string) (*m return r0, r1 } +// GetZone +func (_m *Client) GetZone(ctx *context.Context, zoneID string) (*model.ZoneSpec, error) { + ret := _m.Called(ctx, zoneID) + + var r0 *model.ZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, string) *model.ZoneSpec); ok { + r0 = rf(ctx, zoneID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.ZoneSpec) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*context.Context, string) error); ok { + r1 = rf(ctx, zoneID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // ListAttachmentsByVolumeId provides a mock function with given fields: ctx, volId func (_m *Client) ListAttachmentsByVolumeId(ctx *context.Context, volId string) ([]*model.VolumeAttachmentSpec, error) { ret := _m.Called(ctx, volId) @@ -916,35 +976,6 @@ func (_m *Client) ListAvailabilityZones(ctx *context.Context) ([]string, error) return r0, r1 } -// GetZone -func (_m *Client) GetZone(ctx *context.Context, zoneID string) (*model.ZoneSpec, error) { - return nil, nil -} - -// CreateZone -func (_m *Client) CreateZone(ctx *context.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return nil, nil -} - -// UpdateZone -func (_m *Client) UpdateZone(ctx *context.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return nil, nil -} - -// DeleteZone -func (_m *Client) DeleteZone(ctx *context.Context, zoneID string) error { - return nil -} - -// ListZonesWithFilter -func (_m *Client) ListZonesWithFilter(ctx *context.Context, m map[string][]string) ([]*model.ZoneSpec, error) { - return nil, nil -} - -func (f_m *Client) ListZones(ctx *context.Context) ([]*model.ZoneSpec, error) { - return nil, nil -} - // ListCustomProperties provides a mock function with given fields: ctx, prfID func (_m *Client) ListCustomProperties(ctx *context.Context, prfID string) (*model.CustomPropertiesSpec, error) { ret := _m.Called(ctx, prfID) @@ -1658,6 +1689,52 @@ func (_m *Client) ListVolumesWithFilter(ctx *context.Context, m map[string][]str return r0, r1 } +// ListZones +func (_m *Client) ListZones(ctx *context.Context) ([]*model.ZoneSpec, error) { + ret := _m.Called(ctx) + + var r0 []*model.ZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context) []*model.ZoneSpec); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.ZoneSpec) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ListZonesWithFilter +func (_m *Client) ListZonesWithFilter(ctx *context.Context, m map[string][]string) ([]*model.ZoneSpec, error) { + ret := _m.Called(ctx, m) + + var r0 []*model.ZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, map[string][]string) []*model.ZoneSpec); ok { + r0 = rf(ctx, m) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*model.ZoneSpec) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*context.Context, map[string][]string) error); ok { + r1 = rf(ctx, m) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // RemoveCustomProperty provides a mock function with given fields: ctx, prfID, customKey func (_m *Client) RemoveCustomProperty(ctx *context.Context, prfID string, customKey string) error { ret := _m.Called(ctx, prfID, customKey) @@ -1984,3 +2061,26 @@ func (_m *Client) VolumesToUpdate(ctx *context.Context, volumeList []*model.Volu return r0, r1 } + +// UpdateZone +func (_m *Client) UpdateZone(ctx *context.Context, zoneID string, input *model.ZoneSpec) (*model.ZoneSpec, error) { + ret := _m.Called(ctx, zoneID, input) + + var r0 *model.ZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, string, *model.ZoneSpec) *model.ZoneSpec); ok { + r0 = rf(ctx, zoneID, input) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*model.ZoneSpec) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*context.Context, string, *model.ZoneSpec) error); ok { + r1 = rf(ctx, zoneID, input) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} From 5334bd91fa27006f4466629ff57569f8a3f762ed Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Wed, 13 Nov 2019 11:56:17 +0530 Subject: [PATCH 4/7] Add testcases for zone osdsctl --- osdsctl/cli/zone_test.go | 73 ++++++++++++++++++++++ osdsctl/completion/osdsctl.bash_completion | 4 +- testutils/db/fake.go | 20 ++++-- 3 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 osdsctl/cli/zone_test.go diff --git a/osdsctl/cli/zone_test.go b/osdsctl/cli/zone_test.go new file mode 100644 index 000000000..607de6f3e --- /dev/null +++ b/osdsctl/cli/zone_test.go @@ -0,0 +1,73 @@ +// 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 cli + +import ( + "os" + "os/exec" + "testing" + + c "github.com/opensds/opensds/client" + . "github.com/opensds/opensds/testutils/collection" +) + +func init() { + client = c.NewFakeClient(&c.Config{Endpoint: c.TestEp}) +} + +func TestZoneAction(t *testing.T) { + beCrasher := os.Getenv("BE_CRASHER") + + if beCrasher == "1" { + var args []string + zoneAction(zoneCommand, args) + + return + } + + cmd := exec.Command(os.Args[0], "-test.run=TestZoneAction") + cmd.Env = append(os.Environ(), "BE_CRASHER=1") + err := cmd.Run() + e, ok := err.(*exec.ExitError) + + if ok && ("exit status 1" == e.Error()) { + return + } + + t.Fatalf("process ran with %s, want exit status 1", e.Error()) +} + +func TestZoneCreateAction(t *testing.T) { + var args []string + args = append(args, ByteZone) + zoneCreateAction(zoneCreateCommand, args) +} + +func TestZoneShowAction(t *testing.T) { + var args []string + args = append(args, "1106b972-66ef-11e7-b172-db03f3689c9c") + zoneShowAction(zoneShowCommand, args) +} + +func TestZoneListAction(t *testing.T) { + var args []string + zoneListAction(zoneListCommand, args) +} + +func TestZoneDeleteAction(t *testing.T) { + var args []string + args = append(args, "1106b972-66ef-11e7-b172-db03f3689c9c") + zoneDeleteAction(zoneDeleteCommand, args) +} diff --git a/osdsctl/completion/osdsctl.bash_completion b/osdsctl/completion/osdsctl.bash_completion index 3c5a819ab..8e0a79e1f 100644 --- a/osdsctl/completion/osdsctl.bash_completion +++ b/osdsctl/completion/osdsctl.bash_completion @@ -20,13 +20,15 @@ _osdsctl() { local pre=${COMP_WORDS[COMP_CWORD-1]}; case "$COMP_CWORD $pre" in "1 osdsctl") - COMPREPLY=($(compgen -W 'dock pool profile version volume fileshare host' -- $cur)) ;; + COMPREPLY=($(compgen -W 'dock pool profile version volume fileshare host zone' -- $cur)) ;; "2 dock") COMPREPLY=($(compgen -W 'list show' -- $cur)) ;; "2 pool") COMPREPLY=($(compgen -W 'list show' -- $cur)) ;; "2 profile") COMPREPLY=($(compgen -W 'create delete list show' -- $cur)) ;; + "2 zone") + COMPREPLY=($(compgen -W 'create delete list show' -- $cur)) ;; "2 version") COMPREPLY=($(compgen -W 'list show' -- $cur)) ;; "2 volume") diff --git a/testutils/db/fake.go b/testutils/db/fake.go index 1a51e0931..917c3b156 100755 --- a/testutils/db/fake.go +++ b/testutils/db/fake.go @@ -232,17 +232,17 @@ func (fc *FakeDbClient) ListAvailabilityZones(ctx *c.Context) ([]string, error) // GetZone func (fc *FakeDbClient) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) { - return nil, nil + return &SampleZones[0], nil } // CreateZone func (fc *FakeDbClient) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return nil, nil + return &SampleZones[0], nil } // UpdateZone func (fc *FakeDbClient) UpdateZone(ctx *c.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return nil, nil + return &SampleZones[0], nil } // DeleteZone @@ -252,11 +252,21 @@ func (fc *FakeDbClient) DeleteZone(ctx *c.Context, zoneID string) error { // ListZonesWithFilter func (fc *FakeDbClient) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) { - return nil, nil + var zones []*model.ZoneSpec + + for z := range SampleZones { + zones = append(zones, &SampleZones[z]) + } + return zones, nil } func (fc *FakeDbClient) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { - return nil, nil + var zones []*model.ZoneSpec + + for z := range SampleZones { + zones = append(zones, &SampleZones[z]) + } + return zones, nil } // UpdateDock From c9efe742cc90bfee279fbe8c95f2bbb41ff0da75 Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Thu, 14 Nov 2019 15:21:54 +0530 Subject: [PATCH 5/7] Add creation of AvailabilityZone on discovery of pool --- pkg/db/drivers/etcd/etcd.go | 17 ++++++++++++----- pkg/dock/discovery/discovery.go | 25 +++++++++++++++++++++++++ pkg/dock/discovery/discovery_test.go | 14 ++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/pkg/db/drivers/etcd/etcd.go b/pkg/db/drivers/etcd/etcd.go index 750b41e9e..923af2fdb 100644 --- a/pkg/db/drivers/etcd/etcd.go +++ b/pkg/db/drivers/etcd/etcd.go @@ -1387,10 +1387,16 @@ func (c *Client) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSp zone.CreatedAt = time.Now().Format(constants.TimeFormat) } - // zone name must be unique. - // if _, err := c.getZoneByName(ctx, zone.Name); err == nil { - // return nil, fmt.Errorf("the zone name '%s' already exists", zone.Name) - // } + // zone name and id must be unique. + azs, err := c.ListZones(ctx) + for _, az := range azs { + if az.Name == zone.Name { + return nil, fmt.Errorf("the zone name '%s' already exists", zone.Name) + } + if az.Id == zone.Id { + return nil, fmt.Errorf("the zone ID '%s' already exists", zone.Id) + } + } zoneBody, err := json.Marshal(zone) if err != nil { @@ -1417,7 +1423,8 @@ func (c *Client) UpdateZone(ctx *c.Context, zoneID string, input *model.ZoneSpec return nil, err } if name := input.Name; name != "" { - z.Name = name + // Update of name is not supported yet + // z.Name = name } if desc := input.Description; desc != "" { z.Description = desc diff --git a/pkg/dock/discovery/discovery.go b/pkg/dock/discovery/discovery.go index 6a62cb277..bafd32c30 100755 --- a/pkg/dock/discovery/discovery.go +++ b/pkg/dock/discovery/discovery.go @@ -317,6 +317,31 @@ func (dr *DockRegister) Register(in interface{}) error { log.Errorf("When create pool %s in db: %v\n", pol.Id, err) return err } + // Check if AZ name for pool, exists else create it + azExists := false + azs, err := dr.c.ListZones(ctx) + if err != nil { + log.Errorf("When list zone %s in db: %v\n", pol.AvailabilityZone, err) + } + for _, az := range azs { + if az.Name == pol.AvailabilityZone { + azExists = true + } + } + if azExists == false { + var z = &model.ZoneSpec { + BaseModel: &model.BaseModel { + Id: "", + }, + Name: pol.AvailabilityZone, + } + + _, err := dr.c.CreateZone(ctx, z) + if err != nil { + log.Errorf("When create zone %s in db: %v\n", pol.AvailabilityZone, err) + return err + } + } break default: return fmt.Errorf("Resource type is not supported!") diff --git a/pkg/dock/discovery/discovery_test.go b/pkg/dock/discovery/discovery_test.go index eb8a8dd31..e68271e6a 100644 --- a/pkg/dock/discovery/discovery_test.go +++ b/pkg/dock/discovery/discovery_test.go @@ -100,6 +100,15 @@ func TestDiscover(t *testing.T) { func TestReport(t *testing.T) { var fdd = NewFakeDockDiscoverer() + var azs []*model.ZoneSpec + var az *model.ZoneSpec + + az = &model.ZoneSpec { + BaseModel: &model.BaseModel { + Id: "", + }, + Name: "default", + } for i := range SampleDocks { fdd.dcks = append(fdd.dcks, &SampleDocks[i]) @@ -107,12 +116,17 @@ func TestReport(t *testing.T) { for i := range SamplePools { fdd.pols = append(fdd.pols, &SamplePools[i]) } + for i := range SampleZones { + azs = append(azs, &SampleZones[i]) + } mockClient := new(dbtest.Client) mockClient.On("CreateDock", c.NewAdminContext(), fdd.dcks[0]).Return(nil, nil) mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[0]).Return(nil, nil) mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[1]).Return(nil, nil) mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[2]).Return(nil, nil) + mockClient.On("ListZones", c.NewAdminContext()).Return(azs, nil) + mockClient.On("CreateZone", c.NewAdminContext(), az).Return(&SampleZones[0], nil) fdd.c = mockClient if err := fdd.Report(); err != nil { From 8de3ce6ac7b895e62dfaef38e7bbb50135b7d4a4 Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Fri, 15 Nov 2019 11:49:44 +0530 Subject: [PATCH 6/7] Update access policy for availability zone --- examples/policy.json | 4 ++++ pkg/api/controllers/zone.go | 10 +++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/policy.json b/examples/policy.json index b6934e2b9..868015ac3 100644 --- a/examples/policy.json +++ b/examples/policy.json @@ -47,6 +47,10 @@ "volume_group:update": "rule:admin_or_owner", "volume_group:delete": "rule:admin_or_owner", "availability_zone:list":"", + "availability_zone:get":"", + "availability_zone:create":"admin_api", + "availability_zone:delete":"admin_api", + "availability_zone:update":"admin_api", "metrics:get": "rule:admin_or_owner", "metrics:collect": "rule:admin_or_owner", "metrics:uploadconf": "rule:admin_api", diff --git a/pkg/api/controllers/zone.go b/pkg/api/controllers/zone.go index aa5391908..bc4ec2d4a 100644 --- a/pkg/api/controllers/zone.go +++ b/pkg/api/controllers/zone.go @@ -59,7 +59,7 @@ func (p *ZonePortal) ListAvailabilityZones() { } func (p *ZonePortal) CreateZone() { - if !policy.Authorize(p.Ctx, "zone:create") { + if !policy.Authorize(p.Ctx, "availability_zone:create") { return } @@ -95,7 +95,7 @@ func (p *ZonePortal) CreateZone() { } func (p *ZonePortal) ListZones() { - if !policy.Authorize(p.Ctx, "zone:list") { + if !policy.Authorize(p.Ctx, "availability_zone:list") { return } @@ -126,7 +126,7 @@ func (p *ZonePortal) ListZones() { } func (p *ZonePortal) GetZone() { - if !policy.Authorize(p.Ctx, "zone:get") { + if !policy.Authorize(p.Ctx, "availability_zone:get") { return } id := p.Ctx.Input.Param(":zoneId") @@ -152,7 +152,7 @@ func (p *ZonePortal) GetZone() { func (p *ZonePortal) UpdateZone() { - if !policy.Authorize(p.Ctx, "zone:update") { + if !policy.Authorize(p.Ctx, "availability_zone:update") { return } @@ -188,7 +188,7 @@ func (p *ZonePortal) UpdateZone() { func (p *ZonePortal) DeleteZone() { - if !policy.Authorize(p.Ctx, "zone:delete") { + if !policy.Authorize(p.Ctx, "availability_zone:delete") { return } id := p.Ctx.Input.Param(":zoneId") From baf8708aa0c1636711cc6c865330b80494a487d4 Mon Sep 17 00:00:00 2001 From: Joseph Vazhappilly Date: Fri, 15 Nov 2019 12:14:12 +0530 Subject: [PATCH 7/7] Clean up the code --- client/client.go | 4 +- client/fake.go | 23 ++++---- client/zone.go | 44 ++++++++-------- client/zone_test.go | 30 +++++------ osdsctl/cli/zone.go | 14 ++--- osdsctl/cli/zone_test.go | 2 +- pkg/api/controllers/pool_test.go | 18 ------- pkg/api/controllers/zone.go | 62 +++++----------------- pkg/api/controllers/zone_test.go | 74 +++++++++++--------------- pkg/api/routers/router.go | 4 +- pkg/db/db.go | 14 +++-- pkg/db/drivers/etcd/etcd.go | 61 ++++++--------------- pkg/db/drivers/etcd/etcd_test.go | 11 ---- pkg/dock/discovery/discovery.go | 6 +-- pkg/dock/discovery/discovery_test.go | 14 ++--- pkg/model/zone.go | 18 +++---- testutils/collection/data.go | 8 ++- testutils/db/fake.go | 48 +++++++---------- testutils/db/testing/client.go | 79 ++++++++++------------------ 19 files changed, 197 insertions(+), 337 deletions(-) diff --git a/client/client.go b/client/client.go index 094f9eb37..76b171cff 100755 --- a/client/client.go +++ b/client/client.go @@ -43,7 +43,7 @@ type Client struct { *ReplicationMgr *FileShareMgr *HostMgr - *ZoneMgr + *AvailabilityZoneMgr cfg *Config } @@ -101,7 +101,7 @@ func NewClient(c *Config) (*Client, error) { ReplicationMgr: NewReplicationMgr(r, c.Endpoint, t), FileShareMgr: NewFileShareMgr(r, c.Endpoint, t), HostMgr: NewHostMgr(r, c.Endpoint, t), - ZoneMgr: NewZoneMgr(r, c.Endpoint, t), + AvailabilityZoneMgr: NewAvailabilityZoneMgr(r, c.Endpoint, t), }, nil } diff --git a/client/fake.go b/client/fake.go index a95d09748..35ce09bb2 100644 --- a/client/fake.go +++ b/client/fake.go @@ -63,13 +63,12 @@ func NewFakeClient(config *Config) *Client { Receiver: NewFakeFileShareReceiver(), Endpoint: config.Endpoint, }, -<<<<<<< 211553282aff0b5c8d3f9d7faec703fbb9d34cdb HostMgr: &HostMgr{ Receiver: NewFakeHostReceiver(), -======= - ZoneMgr: &ZoneMgr{ + Endpoint: config.Endpoint, + }, + AvailabilityZoneMgr: &AvailabilityZoneMgr{ Receiver: NewFakeZoneReceiver(), ->>>>>>> Add testcases for zone client Endpoint: config.Endpoint, }, } @@ -509,8 +508,8 @@ func (*fakeZoneReceiver) Recv( switch strings.ToUpper(method) { case "POST": switch out.(type) { - case *model.ZoneSpec: - if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + case *model.AvailabilityZoneSpec: + if err := json.Unmarshal([]byte(ByteAvailabilityZone), out); err != nil { return err } break @@ -520,13 +519,13 @@ func (*fakeZoneReceiver) Recv( break case "GET": switch out.(type) { - case *model.ZoneSpec: - if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + case *model.AvailabilityZoneSpec: + if err := json.Unmarshal([]byte(ByteAvailabilityZone), out); err != nil { return err } break - case *[]*model.ZoneSpec: - if err := json.Unmarshal([]byte(ByteZones), out); err != nil { + case *[]*model.AvailabilityZoneSpec: + if err := json.Unmarshal([]byte(ByteAvailabilityZones), out); err != nil { return err } break @@ -536,8 +535,8 @@ func (*fakeZoneReceiver) Recv( break case "PUT": switch out.(type) { - case *model.ZoneSpec: - if err := json.Unmarshal([]byte(ByteZone), out); err != nil { + case *model.AvailabilityZoneSpec: + if err := json.Unmarshal([]byte(ByteAvailabilityZone), out); err != nil { return err } break diff --git a/client/zone.go b/client/zone.go index d21cb5b70..c44cf624c 100644 --- a/client/zone.go +++ b/client/zone.go @@ -21,30 +21,30 @@ import ( "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 +// AvailabilityZoneBuilder contains request body of handling a zone request. +// Currently it's assigned as the pointer of AvailabilityZoneSpec struct, but it // could be discussed if it's better to define an interface. -type ZoneBuilder *model.ZoneSpec +type AvailabilityZoneBuilder *model.AvailabilityZoneSpec -// NewZoneMgr -func NewZoneMgr(r Receiver, edp string, tenantId string) *ZoneMgr { - return &ZoneMgr{ +// NewAvailabilityZoneMgr +func NewAvailabilityZoneMgr(r Receiver, edp string, tenantId string) *AvailabilityZoneMgr { + return &AvailabilityZoneMgr{ Receiver: r, Endpoint: edp, TenantId: tenantId, } } -// ZoneMgr -type ZoneMgr struct { +// AvailabilityZoneMgr +type AvailabilityZoneMgr struct { Receiver Endpoint string TenantId string } -// CreateZone -func (p *ZoneMgr) CreateZone(body ZoneBuilder) (*model.ZoneSpec, error) { - var res model.ZoneSpec +// CreateAvailabilityZone +func (p *AvailabilityZoneMgr) CreateAvailabilityZone(body AvailabilityZoneBuilder) (*model.AvailabilityZoneSpec, error) { + var res model.AvailabilityZoneSpec url := strings.Join([]string{ p.Endpoint, urls.GenerateZoneURL(urls.Client, p.TenantId)}, "/") @@ -56,9 +56,9 @@ func (p *ZoneMgr) CreateZone(body ZoneBuilder) (*model.ZoneSpec, error) { return &res, nil } -// GetZone -func (p *ZoneMgr) GetZone(zoneID string) (*model.ZoneSpec, error) { - var res model.ZoneSpec +// GetAvailabilityZone +func (p *AvailabilityZoneMgr) GetAvailabilityZone(zoneID string) (*model.AvailabilityZoneSpec, error) { + var res model.AvailabilityZoneSpec url := strings.Join([]string{ p.Endpoint, urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/") @@ -70,9 +70,9 @@ func (p *ZoneMgr) GetZone(zoneID string) (*model.ZoneSpec, error) { return &res, nil } -// UpdateZone ... -func (p *ZoneMgr) UpdateZone(zoneID string, body ZoneBuilder) (*model.ZoneSpec, error) { - var res model.ZoneSpec +// UpdateAvailabilityZone ... +func (p *AvailabilityZoneMgr) UpdateAvailabilityZone(zoneID string, body AvailabilityZoneBuilder) (*model.AvailabilityZoneSpec, error) { + var res model.AvailabilityZoneSpec url := strings.Join([]string{ p.Endpoint, urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/") @@ -84,9 +84,9 @@ func (p *ZoneMgr) UpdateZone(zoneID string, body ZoneBuilder) (*model.ZoneSpec, return &res, nil } -// ListZones -func (p *ZoneMgr) ListZones(args ...interface{}) ([]*model.ZoneSpec, error) { - var res []*model.ZoneSpec +// ListAvailabilityZones +func (p *AvailabilityZoneMgr) ListAvailabilityZones(args ...interface{}) ([]*model.AvailabilityZoneSpec, error) { + var res []*model.AvailabilityZoneSpec url := strings.Join([]string{ p.Endpoint, @@ -107,8 +107,8 @@ func (p *ZoneMgr) ListZones(args ...interface{}) ([]*model.ZoneSpec, error) { return res, nil } -// DeleteZone -func (p *ZoneMgr) DeleteZone(zoneID string) error { +// DeleteAvailabilityZone +func (p *AvailabilityZoneMgr) DeleteAvailabilityZone(zoneID string) error { url := strings.Join([]string{ p.Endpoint, urls.GenerateZoneURL(urls.Client, p.TenantId, zoneID)}, "/") diff --git a/client/zone_test.go b/client/zone_test.go index 00f5c3a96..56ed8871a 100644 --- a/client/zone_test.go +++ b/client/zone_test.go @@ -21,12 +21,12 @@ import ( "github.com/opensds/opensds/pkg/model" ) -var fzn = &ZoneMgr{ +var fzn = &AvailabilityZoneMgr{ Receiver: NewFakeZoneReceiver(), } -func TestCreateZone(t *testing.T) { - expected := &model.ZoneSpec{ +func TestCreateAvailabilityZone(t *testing.T) { + expected := &model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{ Id: "1106b972-66ef-11e7-b172-db03f3689c9c", }, @@ -34,7 +34,7 @@ func TestCreateZone(t *testing.T) { Description: "default zone", } - zn, err := fzn.CreateZone(&model.ZoneSpec{}) + zn, err := fzn.CreateAvailabilityZone(&model.AvailabilityZoneSpec{}) if err != nil { t.Error(err) return @@ -46,9 +46,9 @@ func TestCreateZone(t *testing.T) { } } -func TestGetZone(t *testing.T) { +func TestGetAvailabilityZone(t *testing.T) { var znID = "1106b972-66ef-11e7-b172-db03f3689c9c" - expected := &model.ZoneSpec{ + expected := &model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{ Id: "1106b972-66ef-11e7-b172-db03f3689c9c", }, @@ -56,7 +56,7 @@ func TestGetZone(t *testing.T) { Description: "default zone", } - zn, err := fzn.GetZone(znID) + zn, err := fzn.GetAvailabilityZone(znID) if err != nil { t.Error(err) return @@ -68,8 +68,8 @@ func TestGetZone(t *testing.T) { } } -func TestListZones(t *testing.T) { - expected := []*model.ZoneSpec{ +func TestListAvailabilityZone(t *testing.T) { + expected := []*model.AvailabilityZoneSpec{ { BaseModel: &model.BaseModel{ Id: "1106b972-66ef-11e7-b172-db03f3689c9c", @@ -86,7 +86,7 @@ func TestListZones(t *testing.T) { }, } - zns, err := fzn.ListZones() + zns, err := fzn.ListAvailabilityZones() if err != nil { t.Error(err) return @@ -98,8 +98,8 @@ func TestListZones(t *testing.T) { } } -func TestUpdateZone(t *testing.T) { - expected := &model.ZoneSpec{ +func TestUpdateAvailabilityZone(t *testing.T) { + expected := &model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{ Id: "1106b972-66ef-11e7-b172-db03f3689c9c", }, @@ -107,7 +107,7 @@ func TestUpdateZone(t *testing.T) { Description: "default zone", } - zn, err := fzn.UpdateZone("1106b972-66ef-11e7-b172-db03f3689c9c", &model.ZoneSpec{}) + zn, err := fzn.UpdateAvailabilityZone("1106b972-66ef-11e7-b172-db03f3689c9c", &model.AvailabilityZoneSpec{}) if err != nil { t.Error(err) return @@ -119,10 +119,10 @@ func TestUpdateZone(t *testing.T) { } } -func TestDeleteZone(t *testing.T) { +func TestDeleteAvailabilityZone(t *testing.T) { var znID = "1106b972-66ef-11e7-b172-db03f3689c9c" - if err := fzn.DeleteZone(znID); err != nil { + if err := fzn.DeleteAvailabilityZone(znID); err != nil { t.Error(err) return } diff --git a/osdsctl/cli/zone.go b/osdsctl/cli/zone.go index ffbdb03f2..066337f0f 100644 --- a/osdsctl/cli/zone.go +++ b/osdsctl/cli/zone.go @@ -97,14 +97,14 @@ var zoneFormatters = FormatterList{} func zoneCreateAction(cmd *cobra.Command, args []string) { ArgsNumCheck(cmd, args, 1) - az := &model.ZoneSpec{} + az := &model.AvailabilityZoneSpec{} if err := json.Unmarshal([]byte(args[0]), az); err != nil { Errorln(err) cmd.Usage() os.Exit(1) } - resp, err := client.CreateZone(az) + resp, err := client.CreateAvailabilityZone(az) if err != nil { Fatalln(HttpErrStrip(err)) } @@ -114,7 +114,7 @@ func zoneCreateAction(cmd *cobra.Command, args []string) { func zoneShowAction(cmd *cobra.Command, args []string) { ArgsNumCheck(cmd, args, 1) - resp, err := client.GetZone(args[0]) + resp, err := client.GetAvailabilityZone(args[0]) if err != nil { Fatalln(HttpErrStrip(err)) } @@ -128,7 +128,7 @@ func zoneListAction(cmd *cobra.Command, args []string) { "sortKey": zoneSortKey, "Id": zoneId, "Name": zoneName, "Description": zoneDescription} - resp, err := client.ListZones(opts) + resp, err := client.ListAvailabilityZones(opts) if err != nil { Fatalln(HttpErrStrip(err)) } @@ -138,7 +138,7 @@ func zoneListAction(cmd *cobra.Command, args []string) { func zoneDeleteAction(cmd *cobra.Command, args []string) { ArgsNumCheck(cmd, args, 1) - err := client.DeleteZone(args[0]) + err := client.DeleteAvailabilityZone(args[0]) if err != nil { Fatalln(HttpErrStrip(err)) } @@ -146,7 +146,7 @@ func zoneDeleteAction(cmd *cobra.Command, args []string) { func zoneUpdateAction(cmd *cobra.Command, args []string) { ArgsNumCheck(cmd, args, 2) - az := &model.ZoneSpec{} + az := &model.AvailabilityZoneSpec{} if err := json.Unmarshal([]byte(args[1]), az); err != nil { Errorln(err) @@ -154,7 +154,7 @@ func zoneUpdateAction(cmd *cobra.Command, args []string) { os.Exit(1) } - resp, err := client.UpdateZone(args[0], az) + resp, err := client.UpdateAvailabilityZone(args[0], az) if err != nil { Fatalln(HttpErrStrip(err)) } diff --git a/osdsctl/cli/zone_test.go b/osdsctl/cli/zone_test.go index 607de6f3e..5749a4d44 100644 --- a/osdsctl/cli/zone_test.go +++ b/osdsctl/cli/zone_test.go @@ -51,7 +51,7 @@ func TestZoneAction(t *testing.T) { func TestZoneCreateAction(t *testing.T) { var args []string - args = append(args, ByteZone) + args = append(args, ByteAvailabilityZone) zoneCreateAction(zoneCreateCommand, args) } diff --git a/pkg/api/controllers/pool_test.go b/pkg/api/controllers/pool_test.go index f4c934ad3..712a7bc6d 100755 --- a/pkg/api/controllers/pool_test.go +++ b/pkg/api/controllers/pool_test.go @@ -32,27 +32,9 @@ 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") } -// 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) { t.Run("Should return 200 if everything works well", func(t *testing.T) { diff --git a/pkg/api/controllers/zone.go b/pkg/api/controllers/zone.go index bc4ec2d4a..beda13ed8 100644 --- a/pkg/api/controllers/zone.go +++ b/pkg/api/controllers/zone.go @@ -22,25 +22,22 @@ package controllers import ( "encoding/json" "fmt" - // "strings" - // log "github.com/golang/glog" "github.com/opensds/opensds/pkg/api/policy" c "github.com/opensds/opensds/pkg/context" "github.com/opensds/opensds/pkg/db" "github.com/opensds/opensds/pkg/model" - // "github.com/opensds/opensds/pkg/utils/constants" ) -type ZonePortal struct { +type AvailabilityZonePortal struct { BasePortal } -func (p *ZonePortal) ListAvailabilityZones() { +func (p *AvailabilityZonePortal) ListAvailabilityZones() { if !policy.Authorize(p.Ctx, "availability_zone:list") { return } - azs, err := db.C.ListZones(c.GetContext(p.Ctx)) + azs, err := db.C.ListAvailabilityZones(c.GetContext(p.Ctx)) if err != nil { errMsg := fmt.Sprintf("get AvailabilityZones failed: %s", err.Error()) p.ErrorHandle(model.ErrorInternalServer, errMsg) @@ -58,12 +55,12 @@ func (p *ZonePortal) ListAvailabilityZones() { return } -func (p *ZonePortal) CreateZone() { +func (p *AvailabilityZonePortal) CreateAvailabilityZone() { if !policy.Authorize(p.Ctx, "availability_zone:create") { return } - var zone = model.ZoneSpec{ + var zone = model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{}, } @@ -75,7 +72,7 @@ func (p *ZonePortal) CreateZone() { } // Call db api module to handle create zone request. - result, err := db.C.CreateZone(c.GetContext(p.Ctx), &zone) + result, err := db.C.CreateAvailabilityZone(c.GetContext(p.Ctx), &zone) if err != nil { errMsg := fmt.Sprintf("create zone failed: %v", err) p.ErrorHandle(model.ErrorBadRequest, errMsg) @@ -94,44 +91,13 @@ func (p *ZonePortal) CreateZone() { return } -func (p *ZonePortal) ListZones() { - if !policy.Authorize(p.Ctx, "availability_zone:list") { - return - } - - m, err := p.GetParameters() - if err != nil { - errMsg := fmt.Sprintf("list zones failed: %v", err) - p.ErrorHandle(model.ErrorBadRequest, errMsg) - return - } - - result, err := db.C.ListZonesWithFilter(c.GetContext(p.Ctx), m) - if err != nil { - errMsg := fmt.Sprintf("list zones failed: %v", err) - p.ErrorHandle(model.ErrorInternalServer, errMsg) - return - } - - // Marshal the result. - body, err := json.Marshal(result) - if err != nil { - errMsg := fmt.Sprintf("marshal zones listed result failed: %v", err) - p.ErrorHandle(model.ErrorInternalServer, errMsg) - return - } - - p.SuccessHandle(StatusOK, body) - return -} - -func (p *ZonePortal) GetZone() { +func (p *AvailabilityZonePortal) GetAvailabilityZone() { if !policy.Authorize(p.Ctx, "availability_zone:get") { return } id := p.Ctx.Input.Param(":zoneId") - result, err := db.C.GetZone(c.GetContext(p.Ctx), id) + result, err := db.C.GetAvailabilityZone(c.GetContext(p.Ctx), id) if err != nil { errMsg := fmt.Sprintf("zone %s not found: %v", id, err) p.ErrorHandle(model.ErrorNotFound, errMsg) @@ -150,13 +116,13 @@ func (p *ZonePortal) GetZone() { return } -func (p *ZonePortal) UpdateZone() { +func (p *AvailabilityZonePortal) UpdateAvailabilityZone() { if !policy.Authorize(p.Ctx, "availability_zone:update") { return } - var zone = model.ZoneSpec{ + var zone = model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{}, } id := p.Ctx.Input.Param(":zoneId") @@ -167,7 +133,7 @@ func (p *ZonePortal) UpdateZone() { return } - result, err := db.C.UpdateZone(c.GetContext(p.Ctx), id, &zone) + result, err := db.C.UpdateAvailabilityZone(c.GetContext(p.Ctx), id, &zone) if err != nil { errMsg := fmt.Sprintf("update zones failed: %v", err) p.ErrorHandle(model.ErrorInternalServer, errMsg) @@ -186,21 +152,21 @@ func (p *ZonePortal) UpdateZone() { return } -func (p *ZonePortal) DeleteZone() { +func (p *AvailabilityZonePortal) DeleteAvailabilityZone() { if !policy.Authorize(p.Ctx, "availability_zone:delete") { return } id := p.Ctx.Input.Param(":zoneId") ctx := c.GetContext(p.Ctx) - zone, err := db.C.GetZone(ctx, id) + zone, err := db.C.GetAvailabilityZone(ctx, id) if err != nil { errMsg := fmt.Sprintf("zone %s not found: %v", id, err) p.ErrorHandle(model.ErrorNotFound, errMsg) return } - err = db.C.DeleteZone(ctx, zone.Id) + err = db.C.DeleteAvailabilityZone(ctx, zone.Id) if err != nil { errMsg := fmt.Sprintf("delete zones failed: %v", err) p.ErrorHandle(model.ErrorInternalServer, errMsg) diff --git a/pkg/api/controllers/zone_test.go b/pkg/api/controllers/zone_test.go index e2df9e163..9458458f0 100644 --- a/pkg/api/controllers/zone_test.go +++ b/pkg/api/controllers/zone_test.go @@ -33,16 +33,16 @@ import ( ) func init() { - var zonePortal ZonePortal - beego.Router("/v1beta/availabilityZones", &zonePortal, "post:CreateZone;get:ListZones") - beego.Router("/v1beta/availabilityZones/:zoneId", &zonePortal, "get:GetZone;put:UpdateZone;delete:DeleteZone") + var zonePortal AvailabilityZonePortal + beego.Router("/v1beta/availabilityZones", &zonePortal, "post:CreateAvailabilityZone;get:ListAvailabilityZones") + beego.Router("/v1beta/availabilityZones/:zoneId", &zonePortal, "get:GetAvailabilityZone;put:UpdateAvailabilityZone;delete:DeleteAvailabilityZone") } //////////////////////////////////////////////////////////////////////////////// // Tests for zone // //////////////////////////////////////////////////////////////////////////////// -func TestCreateZone(t *testing.T) { +func TestCreateAvailabilityZone(t *testing.T) { var fakeBody = `{ "name": "default", "description": "default zone" @@ -50,11 +50,11 @@ func TestCreateZone(t *testing.T) { t.Run("Should return 200 if everything works well", func(t *testing.T) { mockClient := new(dbtest.Client) - mockClient.On("CreateZone", c.NewAdminContext(), &model.ZoneSpec{ + mockClient.On("CreateAvailabilityZone", c.NewAdminContext(), &model.AvailabilityZoneSpec{ BaseModel: &model.BaseModel{}, Name: "default", Description: "default zone", - }).Return(&SampleZones[1], nil) + }).Return(&SampleAvailabilityZones[1], nil) db.C = mockClient r, _ := http.NewRequest("POST", "/v1beta/availabilityZones", strings.NewReader(fakeBody)) @@ -63,14 +63,14 @@ func TestCreateZone(t *testing.T) { httpCtx.Input.SetData("context", c.NewAdminContext()) }) beego.BeeApp.Handlers.ServeHTTP(w, r) - var output model.ZoneSpec + var output model.AvailabilityZoneSpec json.Unmarshal(w.Body.Bytes(), &output) assertTestResult(t, w.Code, 200) - assertTestResult(t, &output, &SampleZones[1]) + assertTestResult(t, &output, &SampleAvailabilityZones[1]) }) } -func TestUpdateZone(t *testing.T) { +func TestUpdateAvailabilityZone(t *testing.T) { var jsonStr = []byte(`{ "id": "2f9c0a04-66ef-11e7-ade2-43158893e017", "name": "test", @@ -81,14 +81,14 @@ func TestUpdateZone(t *testing.T) { "name": "test", "description": "test zone" }`) - var expected model.ZoneSpec + var expected model.AvailabilityZoneSpec json.Unmarshal(expectedJson, &expected) t.Run("Should return 200 if everything works well", func(t *testing.T) { - zone := model.ZoneSpec{BaseModel: &model.BaseModel{}} + zone := model.AvailabilityZoneSpec{BaseModel: &model.BaseModel{}} json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&zone) mockClient := new(dbtest.Client) - mockClient.On("UpdateZone", c.NewAdminContext(), zone.Id, &zone). + mockClient.On("UpdateAvailabilityZone", c.NewAdminContext(), zone.Id, &zone). Return(&expected, nil) db.C = mockClient @@ -98,17 +98,17 @@ func TestUpdateZone(t *testing.T) { httpCtx.Input.SetData("context", c.NewAdminContext()) }) beego.BeeApp.Handlers.ServeHTTP(w, r) - var output model.ZoneSpec + var output model.AvailabilityZoneSpec json.Unmarshal(w.Body.Bytes(), &output) assertTestResult(t, w.Code, 200) assertTestResult(t, &output, &expected) }) t.Run("Should return 500 if update zone with bad request", func(t *testing.T) { - zone := model.ZoneSpec{BaseModel: &model.BaseModel{}} + zone := model.AvailabilityZoneSpec{BaseModel: &model.BaseModel{}} json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&zone) mockClient := new(dbtest.Client) - mockClient.On("UpdateZone", c.NewAdminContext(), zone.Id, &zone). + mockClient.On("UpdateAvailabilityZone", c.NewAdminContext(), zone.Id, &zone). Return(nil, errors.New("db error")) db.C = mockClient @@ -122,18 +122,12 @@ func TestUpdateZone(t *testing.T) { }) } -func TestListZones(t *testing.T) { +func TestListAvailabilityZone(t *testing.T) { t.Run("Should return 200 if everything works well", func(t *testing.T) { - var sampleZones = []*model.ZoneSpec{&SampleZones[1]} + var sampleZones = []*model.AvailabilityZoneSpec{&SampleAvailabilityZones[1]} mockClient := new(dbtest.Client) - m := map[string][]string{ - "offset": {"0"}, - "limit": {"1"}, - "sortDir": {"asc"}, - "sortKey": {"name"}, - } - mockClient.On("ListZonesWithFilter", c.NewAdminContext(), m).Return( + mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return( sampleZones, nil) db.C = mockClient @@ -143,7 +137,7 @@ func TestListZones(t *testing.T) { httpCtx.Input.SetData("context", c.NewAdminContext()) }) beego.BeeApp.Handlers.ServeHTTP(w, r) - var output []*model.ZoneSpec + var output []*model.AvailabilityZoneSpec json.Unmarshal(w.Body.Bytes(), &output) assertTestResult(t, w.Code, 200) assertTestResult(t, output, sampleZones) @@ -151,13 +145,7 @@ func TestListZones(t *testing.T) { t.Run("Should return 500 if list zones with bad request", func(t *testing.T) { mockClient := new(dbtest.Client) - m := map[string][]string{ - "offset": {"0"}, - "limit": {"1"}, - "sortDir": {"asc"}, - "sortKey": {"name"}, - } - mockClient.On("ListZonesWithFilter", c.NewAdminContext(), m).Return(nil, errors.New("db error")) + mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return(nil, errors.New("db error")) db.C = mockClient r, _ := http.NewRequest("GET", "/v1beta/availabilityZones?offset=0&limit=1&sortDir=asc&sortKey=name", nil) @@ -170,12 +158,12 @@ func TestListZones(t *testing.T) { }) } -func TestGetZone(t *testing.T) { +func TestGetAvailabilityZone(t *testing.T) { t.Run("Should return 200 if everything works well", func(t *testing.T) { mockClient := new(dbtest.Client) - mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017"). - Return(&SampleZones[1], nil) + mockClient.On("GetAvailabilityZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017"). + Return(&SampleAvailabilityZones[1], nil) db.C = mockClient r, _ := http.NewRequest("GET", "/v1beta/availabilityZones/2f9c0a04-66ef-11e7-ade2-43158893e017", nil) @@ -184,15 +172,15 @@ func TestGetZone(t *testing.T) { httpCtx.Input.SetData("context", c.NewAdminContext()) }) beego.BeeApp.Handlers.ServeHTTP(w, r) - var output model.ZoneSpec + var output model.AvailabilityZoneSpec json.Unmarshal(w.Body.Bytes(), &output) assertTestResult(t, w.Code, 200) - assertTestResult(t, &output, &SampleZones[1]) + assertTestResult(t, &output, &SampleAvailabilityZones[1]) }) t.Run("Should return 404 if get zone with bad request", func(t *testing.T) { mockClient := new(dbtest.Client) - mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + mockClient.On("GetAvailabilityZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( nil, errors.New("db error")) db.C = mockClient @@ -207,13 +195,13 @@ func TestGetZone(t *testing.T) { }) } -func TestDeleteZone(t *testing.T) { +func TestDeleteAvailabilityZone(t *testing.T) { t.Run("Should return 200 if everything works well", func(t *testing.T) { mockClient := new(dbtest.Client) - mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( - &SampleZones[1], nil) - mockClient.On("DeleteZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return(nil) + mockClient.On("GetAvailabilityZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + &SampleAvailabilityZones[1], nil) + mockClient.On("DeleteAvailabilityZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return(nil) db.C = mockClient r, _ := http.NewRequest("DELETE", @@ -228,7 +216,7 @@ func TestDeleteZone(t *testing.T) { t.Run("Should return 404 if delete zone with bad request", func(t *testing.T) { mockClient := new(dbtest.Client) - mockClient.On("GetZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( + mockClient.On("GetAvailabilityZone", c.NewAdminContext(), "2f9c0a04-66ef-11e7-ade2-43158893e017").Return( nil, errors.New("Invalid resource uuid")) db.C = mockClient diff --git a/pkg/api/routers/router.go b/pkg/api/routers/router.go index 66f214886..bd5538136 100755 --- a/pkg/api/routers/router.go +++ b/pkg/api/routers/router.go @@ -60,8 +60,8 @@ func init() { // ListPools and GetPool are used for checking the status of backend pool, admin only beego.NSRouter("/:tenantId/pools", &controllers.PoolPortal{}, "get:ListPools"), beego.NSRouter("/:tenantId/pools/:poolId", &controllers.PoolPortal{}, "get:GetPool"), - beego.NSRouter("/:tenantId/availabilityZones", &controllers.ZonePortal{}, "get:ListAvailabilityZones;post:CreateZone"), - beego.NSRouter("/:tenantId/availabilityZones/:zoneId", &controllers.ZonePortal{}, "get:GetZone;put:UpdateZone;delete:DeleteZone"), + beego.NSRouter("/:tenantId/availabilityZones", &controllers.AvailabilityZonePortal{}, "get:ListAvailabilityZones;post:CreateAvailabilityZone"), + beego.NSRouter("/:tenantId/availabilityZones/:zoneId", &controllers.AvailabilityZonePortal{}, "get:GetAvailabilityZone;put:UpdateAvailabilityZone;delete:DeleteAvailabilityZone"), ) beego.AddNamespace(ns) diff --git a/pkg/db/db.go b/pkg/db/db.go index fb80c2ca1..906a1a068 100755 --- a/pkg/db/db.go +++ b/pkg/db/db.go @@ -115,8 +115,6 @@ 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) @@ -125,17 +123,17 @@ type Client interface { DeletePool(ctx *c.Context, polID string) error - GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) + GetAvailabilityZone(ctx *c.Context, zoneID string) (*model.AvailabilityZoneSpec, error) - CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) + CreateAvailabilityZone(ctx *c.Context, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) - ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) + ListAvailabilityZones(ctx *c.Context) ([]*model.AvailabilityZoneSpec, error) - ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) + ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.AvailabilityZoneSpec, error) - UpdateZone(ctx *c.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) + UpdateAvailabilityZone(ctx *c.Context, zoneID string, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) - DeleteZone(ctx *c.Context, zoneID string) error + DeleteAvailabilityZone(ctx *c.Context, zoneID string) error CreateProfile(ctx *c.Context, prf *model.ProfileSpec) (*model.ProfileSpec, error) diff --git a/pkg/db/drivers/etcd/etcd.go b/pkg/db/drivers/etcd/etcd.go index 923af2fdb..c9209d469 100644 --- a/pkg/db/drivers/etcd/etcd.go +++ b/pkg/db/drivers/etcd/etcd.go @@ -1332,35 +1332,8 @@ 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 -} - -// GetZone -func (c *Client) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) { +// GetAvailabilityZone +func (c *Client) GetAvailabilityZone(ctx *c.Context, zoneID string) (*model.AvailabilityZoneSpec, error) { dbReq := &Request{ Url: urls.GenerateZoneURL(urls.Etcd, "", zoneID), } @@ -1370,7 +1343,7 @@ func (c *Client) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) return nil, errors.New(dbRes.Error) } - var z = &model.ZoneSpec{} + var z = &model.AvailabilityZoneSpec{} if err := json.Unmarshal([]byte(dbRes.Message[0]), z); err != nil { log.Error("When parsing zone in db:", dbRes.Error) return nil, errors.New(dbRes.Error) @@ -1378,8 +1351,8 @@ func (c *Client) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) return z, nil } -// CreateZone -func (c *Client) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { +// CreateAvailabilityZone +func (c *Client) CreateAvailabilityZone(ctx *c.Context, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { if zone.Id == "" { zone.Id = uuid.NewV4().String() } @@ -1388,7 +1361,7 @@ func (c *Client) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSp } // zone name and id must be unique. - azs, err := c.ListZones(ctx) + azs, err := c.ListAvailabilityZones(ctx) for _, az := range azs { if az.Name == zone.Name { return nil, fmt.Errorf("the zone name '%s' already exists", zone.Name) @@ -1416,9 +1389,9 @@ func (c *Client) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSp return zone, nil } -// UpdateZone -func (c *Client) UpdateZone(ctx *c.Context, zoneID string, input *model.ZoneSpec) (*model.ZoneSpec, error) { - z, err := c.GetZone(ctx, zoneID) +// UpdateAvailabilityZone +func (c *Client) UpdateAvailabilityZone(ctx *c.Context, zoneID string, input *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { + z, err := c.GetAvailabilityZone(ctx, zoneID) if err != nil { return nil, err } @@ -1448,8 +1421,8 @@ func (c *Client) UpdateZone(ctx *c.Context, zoneID string, input *model.ZoneSpec return z, nil } -// DeleteZone -func (c *Client) DeleteZone(ctx *c.Context, zoneID string) error { +// DeleteAvailabilityZone +func (c *Client) DeleteAvailabilityZone(ctx *c.Context, zoneID string) error { dbReq := &Request{ Url: urls.GenerateZoneURL(urls.Etcd, "", zoneID), } @@ -1462,8 +1435,8 @@ func (c *Client) DeleteZone(ctx *c.Context, zoneID string) error { } //ListZonesWithFilter -func (c *Client) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) { - zones, err := c.ListZones(ctx) +func (c *Client) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.AvailabilityZoneSpec, error) { + zones, err := c.ListAvailabilityZones(ctx) if err != nil { log.Error("List zones failed: ", err.Error()) return nil, err @@ -1476,8 +1449,8 @@ func (c *Client) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]* return zones, nil } -//ListZones -func (c *Client) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { +//ListAvailabilityZones +func (c *Client) ListAvailabilityZones(ctx *c.Context) ([]*model.AvailabilityZoneSpec, error) { dbReq := &Request{ Url: urls.GenerateZoneURL(urls.Etcd, ""), } @@ -1486,12 +1459,12 @@ func (c *Client) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { log.Error("Failed to get zone in db:", dbRes.Error) return nil, errors.New(dbRes.Error) } - var azs = []*model.ZoneSpec{} + var azs = []*model.AvailabilityZoneSpec{} if len(dbRes.Message) == 0 { return azs, nil } for _, msg := range dbRes.Message { - var az = &model.ZoneSpec{} + var az = &model.AvailabilityZoneSpec{} if err := json.Unmarshal([]byte(msg), az); err != nil { log.Error("When parsing zone in db:", dbRes.Error) return nil, errors.New(dbRes.Error) diff --git a/pkg/db/drivers/etcd/etcd_test.go b/pkg/db/drivers/etcd/etcd_test.go index df3845879..b0aad1bed 100644 --- a/pkg/db/drivers/etcd/etcd_test.go +++ b/pkg/db/drivers/etcd/etcd_test.go @@ -265,17 +265,6 @@ 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": {"0"}, diff --git a/pkg/dock/discovery/discovery.go b/pkg/dock/discovery/discovery.go index bafd32c30..e97baa4f4 100755 --- a/pkg/dock/discovery/discovery.go +++ b/pkg/dock/discovery/discovery.go @@ -319,7 +319,7 @@ func (dr *DockRegister) Register(in interface{}) error { } // Check if AZ name for pool, exists else create it azExists := false - azs, err := dr.c.ListZones(ctx) + azs, err := dr.c.ListAvailabilityZones(ctx) if err != nil { log.Errorf("When list zone %s in db: %v\n", pol.AvailabilityZone, err) } @@ -329,14 +329,14 @@ func (dr *DockRegister) Register(in interface{}) error { } } if azExists == false { - var z = &model.ZoneSpec { + var z = &model.AvailabilityZoneSpec { BaseModel: &model.BaseModel { Id: "", }, Name: pol.AvailabilityZone, } - _, err := dr.c.CreateZone(ctx, z) + _, err := dr.c.CreateAvailabilityZone(ctx, z) if err != nil { log.Errorf("When create zone %s in db: %v\n", pol.AvailabilityZone, err) return err diff --git a/pkg/dock/discovery/discovery_test.go b/pkg/dock/discovery/discovery_test.go index e68271e6a..ab402c557 100644 --- a/pkg/dock/discovery/discovery_test.go +++ b/pkg/dock/discovery/discovery_test.go @@ -100,10 +100,10 @@ func TestDiscover(t *testing.T) { func TestReport(t *testing.T) { var fdd = NewFakeDockDiscoverer() - var azs []*model.ZoneSpec - var az *model.ZoneSpec + var azs []*model.AvailabilityZoneSpec + var az *model.AvailabilityZoneSpec - az = &model.ZoneSpec { + az = &model.AvailabilityZoneSpec { BaseModel: &model.BaseModel { Id: "", }, @@ -116,8 +116,8 @@ func TestReport(t *testing.T) { for i := range SamplePools { fdd.pols = append(fdd.pols, &SamplePools[i]) } - for i := range SampleZones { - azs = append(azs, &SampleZones[i]) + for i := range SampleAvailabilityZones { + azs = append(azs, &SampleAvailabilityZones[i]) } mockClient := new(dbtest.Client) @@ -125,8 +125,8 @@ func TestReport(t *testing.T) { mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[0]).Return(nil, nil) mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[1]).Return(nil, nil) mockClient.On("CreatePool", c.NewAdminContext(), fdd.pols[2]).Return(nil, nil) - mockClient.On("ListZones", c.NewAdminContext()).Return(azs, nil) - mockClient.On("CreateZone", c.NewAdminContext(), az).Return(&SampleZones[0], nil) + mockClient.On("ListAvailabilityZones", c.NewAdminContext()).Return(azs, nil) + mockClient.On("CreateAvailabilityZone", c.NewAdminContext(), az).Return(&SampleAvailabilityZones[0], nil) fdd.c = mockClient if err := fdd.Report(); err != nil { diff --git a/pkg/model/zone.go b/pkg/model/zone.go index 6c87e034b..6817c2e5a 100644 --- a/pkg/model/zone.go +++ b/pkg/model/zone.go @@ -25,31 +25,31 @@ import ( "github.com/golang/glog" ) -// An OpenSDS zone is identified by a unique name and ID. -type ZoneSpec struct { +// An OpenSDS availability zone is identified by a unique name and ID. +type AvailabilityZoneSpec struct { *BaseModel - // The name of the zone. + // The name of the availability zone. Name string `json:"name,omitempty"` - // The description of the zone. + // The description of the availability zone. // +optional Description string `json:"description,omitempty"` } -func NewZoneFromJson(s string) *ZoneSpec { - p := &ZoneSpec{} +func NewZoneFromJson(s string) *AvailabilityZoneSpec { + p := &AvailabilityZoneSpec{} err := json.Unmarshal([]byte(s), p) if err != nil { - glog.Errorf("Unmarshal json to ZoneSpec failed, %v", err) + glog.Errorf("Unmarshal json to AvailabilityZoneSpec failed, %v", err) } return p } -func (p *ZoneSpec) ToJson() string { +func (p *AvailabilityZoneSpec) ToJson() string { b, err := json.Marshal(p) if err != nil { - glog.Errorf("ZoneSpec convert to json failed, %v", err) + glog.Errorf("AvailabilityZoneSpec convert to json failed, %v", err) } return string(b) } diff --git a/testutils/collection/data.go b/testutils/collection/data.go index db58d8e78..91c83d022 100644 --- a/testutils/collection/data.go +++ b/testutils/collection/data.go @@ -221,9 +221,7 @@ var ( }, } - SampleAvailabilityZones = []string{"default"} - - SampleZones = []model.ZoneSpec{ + SampleAvailabilityZones = []model.AvailabilityZoneSpec{ { BaseModel: &model.BaseModel{ Id: "1106b972-66ef-11e7-b172-db03f3689c9c", @@ -1017,13 +1015,13 @@ var ( } ]` - ByteZone = `{ + ByteAvailabilityZone = `{ "id": "1106b972-66ef-11e7-b172-db03f3689c9c", "name": "default", "description": "default zone" }` - ByteZones = `[ + ByteAvailabilityZones = `[ { "id": "1106b972-66ef-11e7-b172-db03f3689c9c", "name": "default", diff --git a/testutils/db/fake.go b/testutils/db/fake.go index 917c3b156..f8749ede3 100755 --- a/testutils/db/fake.go +++ b/testutils/db/fake.go @@ -220,51 +220,41 @@ 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 -} - -// GetZone -func (fc *FakeDbClient) GetZone(ctx *c.Context, zoneID string) (*model.ZoneSpec, error) { - return &SampleZones[0], nil +// GetAvailabilityZone +func (fc *FakeDbClient) GetAvailabilityZone(ctx *c.Context, zoneID string) (*model.AvailabilityZoneSpec, error) { + return &SampleAvailabilityZones[0], nil } -// CreateZone -func (fc *FakeDbClient) CreateZone(ctx *c.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return &SampleZones[0], nil +// CreateAvailabilityZone +func (fc *FakeDbClient) CreateAvailabilityZone(ctx *c.Context, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { + return &SampleAvailabilityZones[0], nil } -// UpdateZone -func (fc *FakeDbClient) UpdateZone(ctx *c.Context, zoneID string, zone *model.ZoneSpec) (*model.ZoneSpec, error) { - return &SampleZones[0], nil +// UpdateAvailabilityZone +func (fc *FakeDbClient) UpdateAvailabilityZone(ctx *c.Context, zoneID string, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { + return &SampleAvailabilityZones[0], nil } -// DeleteZone -func (fc *FakeDbClient) DeleteZone(ctx *c.Context, zoneID string) error { +// DeleteAvailabilityZone +func (fc *FakeDbClient) DeleteAvailabilityZone(ctx *c.Context, zoneID string) error { return nil } // ListZonesWithFilter -func (fc *FakeDbClient) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.ZoneSpec, error) { - var zones []*model.ZoneSpec +func (fc *FakeDbClient) ListZonesWithFilter(ctx *c.Context, m map[string][]string) ([]*model.AvailabilityZoneSpec, error) { + var zones []*model.AvailabilityZoneSpec - for z := range SampleZones { - zones = append(zones, &SampleZones[z]) + for z := range SampleAvailabilityZones { + zones = append(zones, &SampleAvailabilityZones[z]) } return zones, nil } -func (fc *FakeDbClient) ListZones(ctx *c.Context) ([]*model.ZoneSpec, error) { - var zones []*model.ZoneSpec +func (fc *FakeDbClient) ListAvailabilityZones(ctx *c.Context) ([]*model.AvailabilityZoneSpec, error) { + var zones []*model.AvailabilityZoneSpec - for z := range SampleZones { - zones = append(zones, &SampleZones[z]) + for z := range SampleAvailabilityZones { + zones = append(zones, &SampleAvailabilityZones[z]) } return zones, nil } diff --git a/testutils/db/testing/client.go b/testutils/db/testing/client.go index 30eee50fa..75d58bea9 100644 --- a/testutils/db/testing/client.go +++ b/testutils/db/testing/client.go @@ -311,21 +311,21 @@ func (_m *Client) CreateVolumeSnapshot(ctx *context.Context, vs *model.VolumeSna return r0, r1 } -// CreateZone -func (_m *Client) CreateZone(ctx *context.Context, zone *model.ZoneSpec) (*model.ZoneSpec, error) { +// CreateAvailabilityZone +func (_m *Client) CreateAvailabilityZone(ctx *context.Context, zone *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { ret := _m.Called(ctx, zone) - var r0 *model.ZoneSpec - if rf, ok := ret.Get(0).(func(*context.Context, *model.ZoneSpec) *model.ZoneSpec); ok { + var r0 *model.AvailabilityZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, *model.AvailabilityZoneSpec) *model.AvailabilityZoneSpec); ok { r0 = rf(ctx, zone) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ZoneSpec) + r0 = ret.Get(0).(*model.AvailabilityZoneSpec) } } var r1 error - if rf, ok := ret.Get(1).(func(*context.Context, *model.ZoneSpec) error); ok { + if rf, ok := ret.Get(1).(func(*context.Context, *model.AvailabilityZoneSpec) error); ok { r1 = rf(ctx, zone) } else { r1 = ret.Error(1) @@ -502,8 +502,8 @@ func (_m *Client) DeleteVolumeSnapshot(ctx *context.Context, snapshotID string) return r0 } -// DeleteZone -func (_m *Client) DeleteZone(ctx *context.Context, zoneID string) error { +// DeleteAvailabilityZone +func (_m *Client) DeleteAvailabilityZone(ctx *context.Context, zoneID string) error { ret := _m.Called(ctx, zoneID) var r0 error @@ -907,16 +907,16 @@ func (_m *Client) GetVolumeSnapshot(ctx *context.Context, snapshotID string) (*m return r0, r1 } -// GetZone -func (_m *Client) GetZone(ctx *context.Context, zoneID string) (*model.ZoneSpec, error) { +// GetAvailabilityZone +func (_m *Client) GetAvailabilityZone(ctx *context.Context, zoneID string) (*model.AvailabilityZoneSpec, error) { ret := _m.Called(ctx, zoneID) - var r0 *model.ZoneSpec - if rf, ok := ret.Get(0).(func(*context.Context, string) *model.ZoneSpec); ok { + var r0 *model.AvailabilityZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, string) *model.AvailabilityZoneSpec); ok { r0 = rf(ctx, zoneID) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ZoneSpec) + r0 = ret.Get(0).(*model.AvailabilityZoneSpec) } } @@ -953,29 +953,6 @@ func (_m *Client) ListAttachmentsByVolumeId(ctx *context.Context, volId string) return r0, r1 } -// ListAvailabilityZones provides a mock function with given fields: ctx -func (_m *Client) ListAvailabilityZones(ctx *context.Context) ([]string, error) { - ret := _m.Called(ctx) - - var r0 []string - if rf, ok := ret.Get(0).(func(*context.Context) []string); ok { - r0 = rf(ctx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // ListCustomProperties provides a mock function with given fields: ctx, prfID func (_m *Client) ListCustomProperties(ctx *context.Context, prfID string) (*model.CustomPropertiesSpec, error) { ret := _m.Called(ctx, prfID) @@ -1689,16 +1666,16 @@ func (_m *Client) ListVolumesWithFilter(ctx *context.Context, m map[string][]str return r0, r1 } -// ListZones -func (_m *Client) ListZones(ctx *context.Context) ([]*model.ZoneSpec, error) { +// ListAvailabilityZones +func (_m *Client) ListAvailabilityZones(ctx *context.Context) ([]*model.AvailabilityZoneSpec, error) { ret := _m.Called(ctx) - var r0 []*model.ZoneSpec - if rf, ok := ret.Get(0).(func(*context.Context) []*model.ZoneSpec); ok { + var r0 []*model.AvailabilityZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context) []*model.AvailabilityZoneSpec); ok { r0 = rf(ctx) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.ZoneSpec) + r0 = ret.Get(0).([]*model.AvailabilityZoneSpec) } } @@ -1713,15 +1690,15 @@ func (_m *Client) ListZones(ctx *context.Context) ([]*model.ZoneSpec, error) { } // ListZonesWithFilter -func (_m *Client) ListZonesWithFilter(ctx *context.Context, m map[string][]string) ([]*model.ZoneSpec, error) { +func (_m *Client) ListZonesWithFilter(ctx *context.Context, m map[string][]string) ([]*model.AvailabilityZoneSpec, error) { ret := _m.Called(ctx, m) - var r0 []*model.ZoneSpec - if rf, ok := ret.Get(0).(func(*context.Context, map[string][]string) []*model.ZoneSpec); ok { + var r0 []*model.AvailabilityZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, map[string][]string) []*model.AvailabilityZoneSpec); ok { r0 = rf(ctx, m) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]*model.ZoneSpec) + r0 = ret.Get(0).([]*model.AvailabilityZoneSpec) } } @@ -2062,21 +2039,21 @@ func (_m *Client) VolumesToUpdate(ctx *context.Context, volumeList []*model.Volu return r0, r1 } -// UpdateZone -func (_m *Client) UpdateZone(ctx *context.Context, zoneID string, input *model.ZoneSpec) (*model.ZoneSpec, error) { +// UpdateAvailabilityZone +func (_m *Client) UpdateAvailabilityZone(ctx *context.Context, zoneID string, input *model.AvailabilityZoneSpec) (*model.AvailabilityZoneSpec, error) { ret := _m.Called(ctx, zoneID, input) - var r0 *model.ZoneSpec - if rf, ok := ret.Get(0).(func(*context.Context, string, *model.ZoneSpec) *model.ZoneSpec); ok { + var r0 *model.AvailabilityZoneSpec + if rf, ok := ret.Get(0).(func(*context.Context, string, *model.AvailabilityZoneSpec) *model.AvailabilityZoneSpec); ok { r0 = rf(ctx, zoneID, input) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).(*model.ZoneSpec) + r0 = ret.Get(0).(*model.AvailabilityZoneSpec) } } var r1 error - if rf, ok := ret.Get(1).(func(*context.Context, string, *model.ZoneSpec) error); ok { + if rf, ok := ret.Get(1).(func(*context.Context, string, *model.AvailabilityZoneSpec) error); ok { r1 = rf(ctx, zoneID, input) } else { r1 = ret.Error(1)