github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/clustering/v1/nodes_test.go (about) 1 //go:build acceptance || clustering || policies 2 // +build acceptance clustering policies 3 4 package v1 5 6 import ( 7 "testing" 8 9 "github.com/gophercloud/gophercloud/internal/acceptance/clients" 10 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 11 "github.com/gophercloud/gophercloud/openstack/clustering/v1/nodes" 12 th "github.com/gophercloud/gophercloud/testhelper" 13 ) 14 15 func TestNodesCRUD(t *testing.T) { 16 client, err := clients.NewClusteringV1Client() 17 th.AssertNoErr(t, err) 18 19 profile, err := CreateProfile(t, client) 20 th.AssertNoErr(t, err) 21 defer DeleteProfile(t, client, profile.ID) 22 23 cluster, err := CreateCluster(t, client, profile.ID) 24 th.AssertNoErr(t, err) 25 defer DeleteCluster(t, client, cluster.ID) 26 27 node, err := CreateNode(t, client, cluster.ID, profile.ID) 28 th.AssertNoErr(t, err) 29 defer DeleteNode(t, client, node.ID) 30 31 // Test nodes list 32 allPages, err := nodes.List(client, nil).AllPages() 33 th.AssertNoErr(t, err) 34 35 allNodes, err := nodes.ExtractNodes(allPages) 36 th.AssertNoErr(t, err) 37 38 var found bool 39 for _, v := range allNodes { 40 if v.ID == node.ID { 41 found = true 42 } 43 } 44 45 th.AssertEquals(t, found, true) 46 47 // Test nodes update 48 t.Logf("Attempting to update node %s", node.ID) 49 50 updateOpts := nodes.UpdateOpts{ 51 Metadata: map[string]interface{}{ 52 "bar": "baz", 53 }, 54 } 55 56 res := nodes.Update(client, node.ID, updateOpts) 57 th.AssertNoErr(t, res.Err) 58 59 actionID, err := GetActionID(res.Header) 60 th.AssertNoErr(t, err) 61 62 err = WaitForAction(client, actionID) 63 th.AssertNoErr(t, err) 64 65 node, err = nodes.Get(client, node.ID).Extract() 66 th.AssertNoErr(t, err) 67 68 tools.PrintResource(t, node) 69 tools.PrintResource(t, node.Metadata) 70 } 71 72 // Performs an operation on a node 73 func TestNodesOps(t *testing.T) { 74 choices, err := clients.AcceptanceTestChoicesFromEnv() 75 th.AssertNoErr(t, err) 76 77 client, err := clients.NewClusteringV1Client() 78 th.AssertNoErr(t, err) 79 client.Microversion = "1.4" 80 81 profile, err := CreateProfile(t, client) 82 th.AssertNoErr(t, err) 83 defer DeleteProfile(t, client, profile.ID) 84 85 cluster, err := CreateCluster(t, client, profile.ID) 86 th.AssertNoErr(t, err) 87 defer DeleteCluster(t, client, cluster.ID) 88 89 node, err := CreateNode(t, client, cluster.ID, profile.ID) 90 th.AssertNoErr(t, err) 91 defer DeleteNode(t, client, node.ID) 92 93 ops := []nodes.OperationOpts{ 94 // TODO: Commented out due to backend returns error, as of 2018-12-14 95 //{Operation: nodes.RebuildOperation}, 96 //{Operation: nodes.EvacuateOperation, Params: nodes.OperationParams{"EvacuateHost": node.ID, "EvacuateForce", "True"}}, 97 //{Operation: nodes.ChangePasswordOperation, Params: nodes.OperationParams{"admin_pass": "test"}}, // QEMU guest agent is not enabled. 98 {Operation: nodes.RebootOperation, Params: nodes.OperationParams{"type": "SOFT"}}, 99 {Operation: nodes.LockOperation}, 100 {Operation: nodes.UnlockOperation}, 101 {Operation: nodes.SuspendOperation}, 102 {Operation: nodes.ResumeOperation}, 103 {Operation: nodes.RescueOperation, Params: nodes.OperationParams{"image_ref": choices.ImageID}}, 104 {Operation: nodes.PauseOperation}, 105 {Operation: nodes.UnpauseOperation}, 106 {Operation: nodes.StopOperation}, 107 {Operation: nodes.StartOperation}, 108 } 109 110 for _, op := range ops { 111 opName := string(op.Operation) 112 t.Logf("Attempting to perform '%s' on node: %s", opName, node.ID) 113 actionID, res := nodes.Ops(client, node.ID, op).Extract() 114 th.AssertNoErr(t, res) 115 116 err = WaitForAction(client, actionID) 117 th.AssertNoErr(t, err) 118 119 node, err = nodes.Get(client, node.ID).Extract() 120 th.AssertNoErr(t, err) 121 th.AssertEquals(t, "Operation '"+opName+"' succeeded", node.StatusReason) 122 t.Logf("Successfully performed '%s' on node: %s", opName, node.ID) 123 } 124 } 125 126 func TestNodesRecover(t *testing.T) { 127 client, err := clients.NewClusteringV1Client() 128 th.AssertNoErr(t, err) 129 client.Microversion = "1.6" 130 131 profile, err := CreateProfile(t, client) 132 th.AssertNoErr(t, err) 133 defer DeleteProfile(t, client, profile.ID) 134 135 cluster, err := CreateCluster(t, client, profile.ID) 136 th.AssertNoErr(t, err) 137 defer DeleteCluster(t, client, cluster.ID) 138 139 node, err := CreateNode(t, client, cluster.ID, profile.ID) 140 th.AssertNoErr(t, err) 141 defer DeleteNode(t, client, node.ID) 142 143 checkTrue := true 144 checkFalse := false 145 146 // TODO: nodes.RebuildRecovery is commented out as of 12/14/2018 the API backend can't perform the action without returning error 147 ops := []nodes.RecoverOpts{ 148 // Microversion < 1.6 legacy support where argument DOES NOT support Check 149 {}, 150 {Operation: nodes.RebootRecovery}, 151 // nodes.RecoverOpts{Operation: nodes.RebuildRecovery}, 152 153 // MicroVersion >= 1.6 that supports Check where Check is true 154 {Check: &checkTrue}, 155 {Operation: nodes.RebootRecovery, Check: &checkTrue}, 156 //nodes.RecoverOpts{Operation: nodes.RebuildRecovery, Check: &checkTrue}, 157 158 // MicroVersion >= 1.6 that supports Check where Check is false 159 {Check: &checkFalse}, 160 {Operation: nodes.RebootRecovery, Check: &checkFalse}, 161 //nodes.RecoverOpts{Operation: nodes.RebuildRecovery, Check: &checkFalse}, 162 } 163 164 for _, recoverOpt := range ops { 165 if recoverOpt.Check != nil { 166 t.Logf("Attempting to recover by using '%s' check=%t on node: %s", recoverOpt.Operation, *recoverOpt.Check, node.ID) 167 } else { 168 t.Logf("Attempting to recover by using '%s' on node: %s", recoverOpt.Operation, node.ID) 169 } 170 171 actionID, err := nodes.Recover(client, node.ID, recoverOpt).Extract() 172 th.AssertNoErr(t, err) 173 174 err = WaitForAction(client, actionID) 175 th.AssertNoErr(t, err) 176 if recoverOpt.Check != nil { 177 t.Logf("Successfully recovered by using '%s' check=%t on node: %s", recoverOpt.Operation, *recoverOpt.Check, node.ID) 178 } else { 179 t.Logf("Successfully recovered by using '%s' on node: %s", recoverOpt.Operation, node.ID) 180 } 181 182 node, err := nodes.Get(client, node.ID).Extract() 183 th.AssertNoErr(t, err) 184 tools.PrintResource(t, node) 185 } 186 } 187 188 func TestNodeCheck(t *testing.T) { 189 client, err := clients.NewClusteringV1Client() 190 th.AssertNoErr(t, err) 191 192 profile, err := CreateProfile(t, client) 193 th.AssertNoErr(t, err) 194 defer DeleteProfile(t, client, profile.ID) 195 196 cluster, err := CreateCluster(t, client, profile.ID) 197 th.AssertNoErr(t, err) 198 defer DeleteCluster(t, client, cluster.ID) 199 200 node, err := CreateNode(t, client, cluster.ID, profile.ID) 201 th.AssertNoErr(t, err) 202 defer DeleteNode(t, client, node.ID) 203 204 t.Logf("Attempting to check on node: %s", node.ID) 205 206 actionID, err := nodes.Check(client, node.ID).Extract() 207 th.AssertNoErr(t, err) 208 209 err = WaitForAction(client, actionID) 210 th.AssertNoErr(t, err) 211 212 node, err = nodes.Get(client, node.ID).Extract() 213 th.AssertNoErr(t, err) 214 th.AssertEquals(t, "Check: Node is ACTIVE.", node.StatusReason) 215 tools.PrintResource(t, node) 216 }