github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/sharedfilesystems/v2/shares.go (about) 1 package v2 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "strings" 8 "testing" 9 10 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools" 11 12 "github.com/vnpaycloud-console/gophercloud/v2" 13 "github.com/vnpaycloud-console/gophercloud/v2/openstack/sharedfilesystems/v2/messages" 14 "github.com/vnpaycloud-console/gophercloud/v2/openstack/sharedfilesystems/v2/shares" 15 ) 16 17 // CreateShare will create a share with a name, and a size of 1Gb. An 18 // error will be returned if the share could not be created 19 func CreateShare(t *testing.T, client *gophercloud.ServiceClient, optShareType ...string) (*shares.Share, error) { 20 if testing.Short() { 21 t.Skip("Skipping test that requires share creation in short mode.") 22 } 23 24 iTrue := true 25 shareType := "dhss_false" 26 if len(optShareType) > 0 { 27 shareType = optShareType[0] 28 } 29 createOpts := shares.CreateOpts{ 30 Size: 1, 31 Name: "My Test Share", 32 Description: "My Test Description", 33 ShareProto: "NFS", 34 ShareType: shareType, 35 IsPublic: &iTrue, 36 } 37 38 share, err := shares.Create(context.TODO(), client, createOpts).Extract() 39 if err != nil { 40 t.Logf("Failed to create share") 41 return nil, err 42 } 43 44 _, err = waitForStatus(t, client, share.ID, "available") 45 if err != nil { 46 t.Logf("Failed to get %s share status", share.ID) 47 DeleteShare(t, client, share) 48 return share, err 49 } 50 51 return share, nil 52 } 53 54 // ListShares lists all shares that belong to this tenant's project. 55 // An error will be returned if the shares could not be listed.. 56 func ListShares(t *testing.T, client *gophercloud.ServiceClient) ([]shares.Share, error) { 57 r, err := shares.ListDetail(client, &shares.ListOpts{}).AllPages(context.TODO()) 58 if err != nil { 59 return nil, err 60 } 61 62 return shares.ExtractShares(r) 63 } 64 65 // GrantAccess will grant access to an existing share. A fatal error will occur if 66 // this operation fails. 67 func GrantAccess(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share) (*shares.AccessRight, error) { 68 return shares.GrantAccess(context.TODO(), client, share.ID, shares.GrantAccessOpts{ 69 AccessType: "ip", 70 AccessTo: "0.0.0.0/32", 71 AccessLevel: "ro", 72 }).Extract() 73 } 74 75 // RevokeAccess will revoke an exisiting access of a share. A fatal error will occur 76 // if this operation fails. 77 func RevokeAccess(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share, accessRight *shares.AccessRight) error { 78 return shares.RevokeAccess(context.TODO(), client, share.ID, shares.RevokeAccessOpts{ 79 AccessID: accessRight.ID, 80 }).ExtractErr() 81 } 82 83 // GetAccessRightsSlice will retrieve all access rules assigned to a share. 84 // A fatal error will occur if this operation fails. 85 func GetAccessRightsSlice(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share) ([]shares.AccessRight, error) { 86 return shares.ListAccessRights(context.TODO(), client, share.ID).Extract() 87 } 88 89 // DeleteShare will delete a share. A fatal error will occur if the share 90 // failed to be deleted. This works best when used as a deferred function. 91 func DeleteShare(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share) { 92 err := shares.Delete(context.TODO(), client, share.ID).ExtractErr() 93 if err != nil { 94 if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { 95 return 96 } 97 t.Errorf("Unable to delete share %s: %v", share.ID, err) 98 } 99 100 _, err = waitForStatus(t, client, share.ID, "deleted") 101 if err != nil { 102 t.Errorf("Failed to wait for 'deleted' status for %s share: %v", share.ID, err) 103 } else { 104 t.Logf("Deleted share: %s", share.ID) 105 } 106 } 107 108 // ExtendShare extends the capacity of an existing share 109 func ExtendShare(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share, newSize int) error { 110 return shares.Extend(context.TODO(), client, share.ID, &shares.ExtendOpts{NewSize: newSize}).ExtractErr() 111 } 112 113 // ShrinkShare shrinks the capacity of an existing share 114 func ShrinkShare(t *testing.T, client *gophercloud.ServiceClient, share *shares.Share, newSize int) error { 115 return shares.Shrink(context.TODO(), client, share.ID, &shares.ShrinkOpts{NewSize: newSize}).ExtractErr() 116 } 117 118 func PrintMessages(t *testing.T, c *gophercloud.ServiceClient, id string) error { 119 c.Microversion = "2.37" 120 121 allPages, err := messages.List(c, messages.ListOpts{ResourceID: id}).AllPages(context.TODO()) 122 if err != nil { 123 return fmt.Errorf("Unable to retrieve messages: %v", err) 124 } 125 126 allMessages, err := messages.ExtractMessages(allPages) 127 if err != nil { 128 return fmt.Errorf("Unable to extract messages: %v", err) 129 } 130 131 for _, message := range allMessages { 132 tools.PrintResource(t, message) 133 } 134 135 return nil 136 } 137 138 func waitForStatus(t *testing.T, c *gophercloud.ServiceClient, id, status string) (*shares.Share, error) { 139 var current *shares.Share 140 141 err := tools.WaitFor(func(ctx context.Context) (bool, error) { 142 var err error 143 144 current, err = shares.Get(ctx, c, id).Extract() 145 if err != nil { 146 if gophercloud.ResponseCodeIs(err, http.StatusNotFound) { 147 switch status { 148 case "deleted": 149 return true, nil 150 default: 151 return false, err 152 } 153 } 154 return false, err 155 } 156 157 if current.Status == status { 158 return true, nil 159 } 160 161 if strings.Contains(current.Status, "error") { 162 return true, fmt.Errorf("An error occurred, wrong status: %s", current.Status) 163 } 164 165 return false, nil 166 }) 167 168 if err != nil { 169 mErr := PrintMessages(t, c, id) 170 if mErr != nil { 171 return current, fmt.Errorf("Share status is '%s' and unable to get manila messages: %s", err, mErr) 172 } 173 } 174 175 return current, err 176 }