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  }