Skip to content

Commit

Permalink
snapshot fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Shruthi-1MN committed Dec 9, 2019
1 parent f8581c3 commit aafbb7a
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 77 deletions.
18 changes: 18 additions & 0 deletions pkg/api/controllers/fileshare.go
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,24 @@ func (f *FileShareSnapshotPortal) UpdateFileShareSnapshot() {
}
snapshot.Id = id

reg, err := utils.Special_Character_Regex_Match_Pattern()
if err != nil {
log.Error(err)
return
}
if reg.MatchString(snapshot.Name) {
errMsg := fmt.Sprintf("invalid snapshot name because it has some special characters")
log.Error(errMsg)
f.ErrorHandle(model.ErrorBadRequest, errMsg)
return
}
if reg.MatchString(snapshot.Description) {
errMsg := fmt.Sprintf("invalid snapshot description and it has some special characters")
log.Error(errMsg)
f.ErrorHandle(model.ErrorBadRequest, errMsg)
return
}

result, err := db.C.UpdateFileShareSnapshot(c.GetContext(f.Ctx), id, &snapshot)
if err != nil {
errMsg := fmt.Sprintf("update fileshare snapshot failed: %s", err.Error())
Expand Down
46 changes: 46 additions & 0 deletions pkg/api/controllers/fileshare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,52 @@ func TestUpdateFileShareSnapshot(t *testing.T) {
assertTestResult(t, &output, &expected)
})

t.Run("Should return 400 invalid snapshot name because it has some special characters", func(t *testing.T) {
var jsonStr = []byte(`{
"name": "#Snap !$!test",
"description":"fake snapshot"
}`)
snapshot := model.FileShareSnapshotSpec{BaseModel: &model.BaseModel{}}
json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&snapshot)

mockClient := new(dbtest.Client)
mockClient.On("UpdateFileShareSnapshot", c.NewAdminContext(), snapshot.Id, &snapshot).
Return(&expected, nil)
db.C = mockClient

r, _ := http.NewRequest("PUT", "/v1beta/file/snapshots/3769855c-a102-11e7-b772-17b880d2f537", bytes.NewBuffer(jsonStr))
w := httptest.NewRecorder()
r.Header.Set("Content-Type", "application/JSON")
beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) {
httpCtx.Input.SetData("context", c.NewAdminContext())
})
beego.BeeApp.Handlers.ServeHTTP(w, r)
assertTestResult(t, w.Code, 400)
})

t.Run("Should return 400 invalid snapshot description and it has some special characters", func(t *testing.T) {
var jsonStr = []byte(`{
"name":"fake snapshot",
"description": "#Share !$!test"
}`)
snapshot := model.FileShareSnapshotSpec{BaseModel: &model.BaseModel{}}
json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&snapshot)

mockClient := new(dbtest.Client)
mockClient.On("UpdateFileShareSnapshot", c.NewAdminContext(), snapshot.Id, &snapshot).
Return(&expected, nil)
db.C = mockClient

r, _ := http.NewRequest("PUT", "/v1beta/file/snapshots/3769855c-a102-11e7-b772-17b880d2f537", bytes.NewBuffer(jsonStr))
w := httptest.NewRecorder()
r.Header.Set("Content-Type", "application/JSON")
beego.InsertFilter("*", beego.BeforeExec, func(httpCtx *context.Context) {
httpCtx.Input.SetData("context", c.NewAdminContext())
})
beego.BeeApp.Handlers.ServeHTTP(w, r)
assertTestResult(t, w.Code, 400)
})

t.Run("Should return 500 if update fileshare snapshot with bad request", func(t *testing.T) {
snapshot := model.FileShareSnapshotSpec{BaseModel: &model.BaseModel{}}
json.NewDecoder(bytes.NewBuffer(jsonStr)).Decode(&snapshot)
Expand Down
27 changes: 13 additions & 14 deletions pkg/api/util/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,17 +170,6 @@ func CreateFileShareDBEntry(ctx *c.Context, in *model.FileShareSpec) (*model.Fil
if in.UpdatedAt == "" {
in.UpdatedAt = time.Now().Format(constants.TimeFormat)
}
//validate the name
if in.Name == "" {
errMsg := fmt.Sprintf("empty fileshare name is not allowed. Please give valid name.")
log.Error(errMsg)
return nil, errors.New(errMsg)
}
if len(in.Name) > 255 {
errMsg := fmt.Sprintf("fileshare name length should not be more than 255 characters. input name length is : %d", len(in.Name))
log.Error(errMsg)
return nil, errors.New(errMsg)
}

reg, err := regexp.Compile("^[a-zA-Z0-9_-]+$")
if err != nil {
Expand Down Expand Up @@ -281,9 +270,19 @@ func CreateFileShareSnapshotDBEntry(ctx *c.Context, in *model.FileShareSnapshotS
in.CreatedAt = time.Now().Format(constants.TimeFormat)
}

//validate the snapshot name
if in.Name == "" {
errMsg := fmt.Sprintf("snapshot name can not be empty. Please give valid snapshot name")
reg, err := utils.Special_Character_Regex_Match_Pattern()
if err != nil {
errMsg := fmt.Sprintf("regex compilation for file share description validation failed")
log.Error(errMsg)
return nil, errors.New(errMsg)
}
if reg.MatchString(in.Name) {
errMsg := fmt.Sprintf("invalid fileshare snapshot name because it has some special characters")
log.Error(errMsg)
return nil, errors.New(errMsg)
}
if reg.MatchString(in.Description) {
errMsg := fmt.Sprintf("invalid fileshare snapshot description because it has some special characters")
log.Error(errMsg)
return nil, errors.New(errMsg)
}
Expand Down
104 changes: 41 additions & 63 deletions pkg/api/util/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package util
import (
"fmt"
"reflect"
"strconv"
"testing"

"github.com/opensds/opensds/pkg/utils"
Expand Down Expand Up @@ -375,6 +374,47 @@ func TestCreateFileShareSnapshotDBEntry(t *testing.T) {
assertTestResult(t, result, expected)
})

t.Run("invalid fileshare snapshot description because it has some special characters", func(t *testing.T) {
req.Name = "testsnap"
req.Description = "#Snap !$!test"
mockClient := new(dbtest.Client)
mockClient.On("GetFileShare", context.NewAdminContext(), "bd5b12a8-a101-11e7-941e-d77981b584d8").Return(fileshare, nil)
mockClient.On("ListFileShareSnapshots", context.NewAdminContext()).Return(nil, nil)
mockClient.On("CreateFileShareSnapshot", context.NewAdminContext(), req).Return(&SampleShareSnapshots[0], nil)
db.C = mockClient

_, err := CreateFileShareSnapshotDBEntry(context.NewAdminContext(), req)
expectedError := fmt.Sprintf("invalid fileshare snapshot description because it has some special characters")
assertTestResult(t, err.Error(), expectedError)
})

t.Run("invalid fileshare snapshot name because it has some special characters", func(t *testing.T) {
req.Name = "#Snap !$!test"
req.Description = "test snapshot"
mockClient := new(dbtest.Client)
mockClient.On("GetFileShare", context.NewAdminContext(), "bd5b12a8-a101-11e7-941e-d77981b584d8").Return(fileshare, nil)
mockClient.On("ListFileShareSnapshots", context.NewAdminContext()).Return(nil, nil)
mockClient.On("CreateFileShareSnapshot", context.NewAdminContext(), req).Return(&SampleShareSnapshots[0], nil)
db.C = mockClient

_, err := CreateFileShareSnapshotDBEntry(context.NewAdminContext(), req)
expectedError := fmt.Sprintf("invalid fileshare snapshot name because it has some special characters")
assertTestResult(t, err.Error(), expectedError)
})

t.Run("names starting 'snapshot' are reserved", func(t *testing.T) {
req.Name = "snapshotknow"
req.Description = "test snapshot"
mockClient := new(dbtest.Client)
mockClient.On("GetFileShare", context.NewAdminContext(), "bd5b12a8-a101-11e7-941e-d77981b584d8").Return(fileshare, nil)
mockClient.On("ListFileShareSnapshots", context.NewAdminContext()).Return(nil, nil)
mockClient.On("CreateFileShareSnapshot", context.NewAdminContext(), req).Return(&SampleShareSnapshots[0], nil)
db.C = mockClient

_, err := CreateFileShareSnapshotDBEntry(context.NewAdminContext(), req)
expectedError := fmt.Sprintf("names starting 'snapshot' are reserved. Please choose a different snapshot name.")
assertTestResult(t, err.Error(), expectedError)
})
}

func TestCreateFileShareDBEntry(t *testing.T) {
Expand Down Expand Up @@ -422,44 +462,6 @@ func TestCreateFileShareDBEntry(t *testing.T) {
assertTestResult(t, err.Error(), expectedError)
})

t.Run("Empty file share name is allowed", func(t *testing.T) {
in.Size, in.Name, in.ProfileId = int64(1), "", "b3585ebe-c42c-120g-b28e-f373746a71ca"
mockClient := new(dbtest.Client)
mockClient.On("CreateFileShare", context.NewAdminContext(), in).Return(&SampleFileShares[0], nil)
db.C = mockClient

_, err := CreateFileShareDBEntry(context.NewAdminContext(), in)
expectedError := "empty fileshare name is not allowed. Please give valid name."
assertTestResult(t, err.Error(), expectedError)
})

t.Run("File share name length equal to 0 character are not allowed", func(t *testing.T) {
in.Name = utils.RandSeqWithAlnum(0)
in.Size, in.ProfileId = int64(1), "b3585ebe-c42c-120g-b28e-f373746a71ca"
mockClient := new(dbtest.Client)
mockClient.On("CreateFileShare", context.NewAdminContext(), in).Return(&SampleFileShares[0], nil)
db.C = mockClient

_, err := CreateFileShareDBEntry(context.NewAdminContext(), in)
expectedError := "empty fileshare name is not allowed. Please give valid name."
assertTestResult(t, err.Error(), expectedError)
})

t.Run("File share name length equal to 1 character are allowed", func(t *testing.T) {
in.Name = utils.RandSeqWithAlnum(1)
in.Size, in.ProfileId = int64(1), "b3585ebe-c42c-120g-b28e-f373746a71ca"
mockClient := new(dbtest.Client)
mockClient.On("CreateFileShare", context.NewAdminContext(), in).Return(&SampleFileShares[0], nil)
db.C = mockClient

var expected = &SampleFileShares[0]
result, err := CreateFileShareDBEntry(context.NewAdminContext(), in)
if err != nil {
t.Errorf("failed to create fileshare err is %v\n", err)
}
assertTestResult(t, result, expected)
})

t.Run("File share name length equal to 10 characters are allowed", func(t *testing.T) {
in.Name = utils.RandSeqWithAlnum(10)
in.Size, in.ProfileId = int64(1), "b3585ebe-c42c-120g-b28e-f373746a71ca"
Expand Down Expand Up @@ -504,30 +506,6 @@ func TestCreateFileShareDBEntry(t *testing.T) {
}
assertTestResult(t, result, expected)
})

t.Run("File share name length more than 255 characters are not allowed", func(t *testing.T) {
in.Name = utils.RandSeqWithAlnum(256)
in.Size, in.ProfileId = int64(1), "b3585ebe-c42c-120g-b28e-f373746a71ca"
mockClient := new(dbtest.Client)
mockClient.On("CreateFileShare", context.NewAdminContext(), in).Return(&SampleFileShares[0], nil)
db.C = mockClient

_, err := CreateFileShareDBEntry(context.NewAdminContext(), in)
expectedError := "fileshare name length should not be more than 255 characters. input name length is : " + strconv.Itoa(len(in.Name))
assertTestResult(t, err.Error(), expectedError)
})

t.Run("File share name length more than 255 characters are not allowed", func(t *testing.T) {
in.Name = utils.RandSeqWithAlnum(257)
in.Size, in.ProfileId = int64(1), "b3585ebe-c42c-120g-b28e-f373746a71ca"
mockClient := new(dbtest.Client)
mockClient.On("CreateFileShare", context.NewAdminContext(), in).Return(&SampleFileShares[0], nil)
db.C = mockClient

_, err := CreateFileShareDBEntry(context.NewAdminContext(), in)
expectedError := "fileshare name length should not be more than 255 characters. input name length is : " + strconv.Itoa(len(in.Name))
assertTestResult(t, err.Error(), expectedError)
})
}

func TestDeleteFileShareDBEntry(t *testing.T) {
Expand Down
22 changes: 22 additions & 0 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"reflect"
"sort"
"strings"
"regexp"
"time"

"github.com/opensds/opensds/pkg/utils/constants"
Expand Down Expand Up @@ -336,3 +337,24 @@ func ContainsIgnoreCase(a []string, x string) bool {
}
return false
}

func RandomString(n int) string {
var letter = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

b := make([]rune, n)
for i := range b {
b[i] = letter[rand.Intn(len(letter))]
}
return string(b)
}

func Special_Character_Regex_Match_Pattern() (*regexp.Regexp, error) {
reg, err := regexp.Compile("[^a-zA-Z0-9 _-]+")
if err != nil {
errMsg := fmt.Sprintf("regex compilation validation failed")
log.Error(errMsg)
return nil, errors.New(errMsg)
} else {
return reg, nil
}
}

0 comments on commit aafbb7a

Please sign in to comment.