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