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  }