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