github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/containerinfra/v1/nodegroups_test.go (about)

     1  //go:build acceptance || containerinfra || nodegroups
     2  
     3  package v1
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"net/http"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/vnpaycloud-console/gophercloud/v2"
    13  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/clients"
    14  	"github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools"
    15  	"github.com/vnpaycloud-console/gophercloud/v2/openstack/containerinfra/v1/nodegroups"
    16  	th "github.com/vnpaycloud-console/gophercloud/v2/testhelper"
    17  )
    18  
    19  func TestNodeGroupsCRUD(t *testing.T) {
    20  	t.Skip("Failure to deploy cluster in CI")
    21  	// API not available until Magnum train
    22  	clients.SkipRelease(t, "stable/mitaka")
    23  	clients.SkipRelease(t, "stable/newton")
    24  	clients.SkipRelease(t, "stable/ocata")
    25  	clients.SkipRelease(t, "stable/pike")
    26  	clients.SkipRelease(t, "stable/queens")
    27  	clients.SkipRelease(t, "stable/rocky")
    28  	clients.SkipRelease(t, "stable/stein")
    29  
    30  	client, err := clients.NewContainerInfraV1Client()
    31  	th.AssertNoErr(t, err)
    32  
    33  	client.Microversion = "1.9"
    34  
    35  	clusterTemplate, err := CreateKubernetesClusterTemplate(t, client)
    36  	th.AssertNoErr(t, err)
    37  	defer DeleteClusterTemplate(t, client, clusterTemplate.UUID)
    38  
    39  	clusterID, err := CreateKubernetesCluster(t, client, clusterTemplate.UUID)
    40  	th.AssertNoErr(t, err)
    41  	defer DeleteCluster(t, client, clusterID)
    42  
    43  	var nodeGroupID string
    44  
    45  	t.Run("list", func(t *testing.T) { testNodeGroupsList(t, client, clusterID) })
    46  	t.Run("listone-get", func(t *testing.T) { testNodeGroupGet(t, client, clusterID) })
    47  	t.Run("create", func(t *testing.T) { nodeGroupID = testNodeGroupCreate(t, client, clusterID) })
    48  
    49  	t.Logf("Created nodegroup: %s", nodeGroupID)
    50  
    51  	// Wait for the node group to finish creating
    52  	err = tools.WaitForTimeout(func(ctx context.Context) (bool, error) {
    53  		ng, err := nodegroups.Get(ctx, client, clusterID, nodeGroupID).Extract()
    54  		if err != nil {
    55  			return false, fmt.Errorf("error waiting for node group to create: %v", err)
    56  		}
    57  		return (ng.Status == "CREATE_COMPLETE"), nil
    58  	}, 900*time.Second)
    59  	th.AssertNoErr(t, err)
    60  
    61  	t.Run("update", func(t *testing.T) { testNodeGroupUpdate(t, client, clusterID, nodeGroupID) })
    62  	t.Run("delete", func(t *testing.T) { testNodeGroupDelete(t, client, clusterID, nodeGroupID) })
    63  }
    64  
    65  func testNodeGroupsList(t *testing.T, client *gophercloud.ServiceClient, clusterID string) {
    66  	allPages, err := nodegroups.List(client, clusterID, nil).AllPages(context.TODO())
    67  	th.AssertNoErr(t, err)
    68  
    69  	allNodeGroups, err := nodegroups.ExtractNodeGroups(allPages)
    70  	th.AssertNoErr(t, err)
    71  
    72  	// By default two node groups should be created
    73  	th.AssertEquals(t, 2, len(allNodeGroups))
    74  }
    75  
    76  func testNodeGroupGet(t *testing.T, client *gophercloud.ServiceClient, clusterID string) {
    77  	listOpts := nodegroups.ListOpts{
    78  		Role: "worker",
    79  	}
    80  	allPages, err := nodegroups.List(client, clusterID, listOpts).AllPages(context.TODO())
    81  	th.AssertNoErr(t, err)
    82  
    83  	allNodeGroups, err := nodegroups.ExtractNodeGroups(allPages)
    84  	th.AssertNoErr(t, err)
    85  
    86  	// Should be one worker node group
    87  	th.AssertEquals(t, 1, len(allNodeGroups))
    88  
    89  	ngID := allNodeGroups[0].UUID
    90  
    91  	ng, err := nodegroups.Get(context.TODO(), client, clusterID, ngID).Extract()
    92  	th.AssertNoErr(t, err)
    93  
    94  	// Should have got the same node group as from the list
    95  	th.AssertEquals(t, ngID, ng.UUID)
    96  	th.AssertEquals(t, "worker", ng.Role)
    97  }
    98  
    99  func testNodeGroupCreate(t *testing.T, client *gophercloud.ServiceClient, clusterID string) string {
   100  	name := tools.RandomString("test-ng-", 8)
   101  
   102  	// have to create two nodes for the Update test (can't set minimum above actual node count)
   103  	two := 2
   104  	createOpts := nodegroups.CreateOpts{
   105  		Name:      name,
   106  		NodeCount: &two,
   107  	}
   108  
   109  	ng, err := nodegroups.Create(context.TODO(), client, clusterID, createOpts).Extract()
   110  	th.AssertNoErr(t, err)
   111  	th.AssertEquals(t, name, ng.Name)
   112  
   113  	return ng.UUID
   114  }
   115  
   116  func testNodeGroupUpdate(t *testing.T, client *gophercloud.ServiceClient, clusterID, nodeGroupID string) {
   117  	// Node group starts with min=1, max=unset
   118  	// Set min, then set max, then set both
   119  
   120  	updateOpts := []nodegroups.UpdateOptsBuilder{
   121  		nodegroups.UpdateOpts{
   122  			Op:    nodegroups.ReplaceOp,
   123  			Path:  "/min_node_count",
   124  			Value: 2,
   125  		},
   126  	}
   127  	ng, err := nodegroups.Update(context.TODO(), client, clusterID, nodeGroupID, updateOpts).Extract()
   128  	th.AssertNoErr(t, err)
   129  	th.AssertEquals(t, 2, ng.MinNodeCount)
   130  
   131  	updateOpts = []nodegroups.UpdateOptsBuilder{
   132  		nodegroups.UpdateOpts{
   133  			Op:    nodegroups.ReplaceOp,
   134  			Path:  "/max_node_count",
   135  			Value: 5,
   136  		},
   137  	}
   138  	ng, err = nodegroups.Update(context.TODO(), client, clusterID, nodeGroupID, updateOpts).Extract()
   139  	th.AssertNoErr(t, err)
   140  	th.AssertEquals(t, false, ng.MaxNodeCount == nil)
   141  	th.AssertEquals(t, 5, *ng.MaxNodeCount)
   142  
   143  	updateOpts = []nodegroups.UpdateOptsBuilder{
   144  		nodegroups.UpdateOpts{
   145  			Op:    nodegroups.ReplaceOp,
   146  			Path:  "/min_node_count",
   147  			Value: 1,
   148  		},
   149  		nodegroups.UpdateOpts{
   150  			Op:    nodegroups.ReplaceOp,
   151  			Path:  "/max_node_count",
   152  			Value: 3,
   153  		},
   154  	}
   155  	ng, err = nodegroups.Update(context.TODO(), client, clusterID, nodeGroupID, updateOpts).Extract()
   156  	th.AssertNoErr(t, err)
   157  	th.AssertEquals(t, false, ng.MaxNodeCount == nil)
   158  	th.AssertEquals(t, 1, ng.MinNodeCount)
   159  	th.AssertEquals(t, 3, *ng.MaxNodeCount)
   160  }
   161  
   162  func testNodeGroupDelete(t *testing.T, client *gophercloud.ServiceClient, clusterID, nodeGroupID string) {
   163  	err := nodegroups.Delete(context.TODO(), client, clusterID, nodeGroupID).ExtractErr()
   164  	th.AssertNoErr(t, err)
   165  
   166  	// Wait for the node group to be deleted
   167  	err = tools.WaitFor(func(ctx context.Context) (bool, error) {
   168  		_, err := nodegroups.Get(ctx, client, clusterID, nodeGroupID).Extract()
   169  		if gophercloud.ResponseCodeIs(err, http.StatusNotFound) {
   170  			return true, nil
   171  		}
   172  		return false, nil
   173  	})
   174  	th.AssertNoErr(t, err)
   175  }