1package v1 2 3import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/gophercloud/gophercloud" 9 "github.com/gophercloud/gophercloud/acceptance/clients" 10 idv3 "github.com/gophercloud/gophercloud/acceptance/openstack/identity/v3" 11 "github.com/gophercloud/gophercloud/acceptance/tools" 12 "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clusters" 13 "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/clustertemplates" 14 "github.com/gophercloud/gophercloud/openstack/containerinfra/v1/quotas" 15 th "github.com/gophercloud/gophercloud/testhelper" 16) 17 18// CreateClusterTemplate will create a random cluster tempalte. An error will be returned if the 19// cluster-template could not be created. 20func CreateClusterTemplate(t *testing.T, client *gophercloud.ServiceClient) (*clustertemplates.ClusterTemplate, error) { 21 choices, err := clients.AcceptanceTestChoicesFromEnv() 22 if err != nil { 23 return nil, err 24 } 25 26 name := tools.RandomString("TESTACC-", 8) 27 t.Logf("Attempting to create cluster template: %s", name) 28 29 boolFalse := false 30 createOpts := clustertemplates.CreateOpts{ 31 COE: "swarm", 32 DNSNameServer: "8.8.8.8", 33 DockerStorageDriver: "devicemapper", 34 ExternalNetworkID: choices.ExternalNetworkID, 35 FlavorID: choices.FlavorID, 36 FloatingIPEnabled: &boolFalse, 37 ImageID: choices.MagnumImageID, 38 MasterFlavorID: choices.FlavorID, 39 MasterLBEnabled: &boolFalse, 40 Name: name, 41 Public: &boolFalse, 42 RegistryEnabled: &boolFalse, 43 ServerType: "vm", 44 } 45 46 res := clustertemplates.Create(client, createOpts) 47 if res.Err != nil { 48 return nil, res.Err 49 } 50 51 requestID := res.Header.Get("X-OpenStack-Request-Id") 52 th.AssertEquals(t, true, requestID != "") 53 54 t.Logf("Cluster Template %s request ID: %s", name, requestID) 55 56 clusterTemplate, err := res.Extract() 57 if err != nil { 58 return nil, err 59 } 60 61 t.Logf("Successfully created cluster template: %s", clusterTemplate.Name) 62 63 tools.PrintResource(t, clusterTemplate) 64 tools.PrintResource(t, clusterTemplate.CreatedAt) 65 66 th.AssertEquals(t, name, clusterTemplate.Name) 67 th.AssertEquals(t, choices.ExternalNetworkID, clusterTemplate.ExternalNetworkID) 68 th.AssertEquals(t, choices.MagnumImageID, clusterTemplate.ImageID) 69 70 return clusterTemplate, nil 71} 72 73// DeleteClusterTemplate will delete a given cluster-template. A fatal error will occur if the 74// cluster-template could not be deleted. This works best as a deferred function. 75func DeleteClusterTemplate(t *testing.T, client *gophercloud.ServiceClient, id string) { 76 t.Logf("Attempting to delete cluster-template: %s", id) 77 78 err := clustertemplates.Delete(client, id).ExtractErr() 79 if err != nil { 80 t.Fatalf("Error deleting cluster-template %s: %s:", id, err) 81 } 82 83 t.Logf("Successfully deleted cluster-template: %s", id) 84 85 return 86} 87 88// CreateCluster will create a random cluster. An error will be returned if the 89// cluster could not be created. 90func CreateCluster(t *testing.T, client *gophercloud.ServiceClient, clusterTemplateID string) (string, error) { 91 clusterName := tools.RandomString("TESTACC-", 8) 92 t.Logf("Attempting to create cluster: %s using template %s", clusterName, clusterTemplateID) 93 94 choices, err := clients.AcceptanceTestChoicesFromEnv() 95 if err != nil { 96 return "", err 97 } 98 99 masterCount := 1 100 nodeCount := 1 101 createTimeout := 100 102 createOpts := clusters.CreateOpts{ 103 ClusterTemplateID: clusterTemplateID, 104 CreateTimeout: &createTimeout, 105 FlavorID: choices.FlavorID, 106 Keypair: choices.MagnumKeypair, 107 Labels: map[string]string{}, 108 MasterCount: &masterCount, 109 MasterFlavorID: choices.FlavorID, 110 Name: clusterName, 111 NodeCount: &nodeCount, 112 } 113 114 createResult := clusters.Create(client, createOpts) 115 th.AssertNoErr(t, createResult.Err) 116 if len(createResult.Header["X-Openstack-Request-Id"]) > 0 { 117 t.Logf("Cluster Create Request ID: %s", createResult.Header["X-Openstack-Request-Id"][0]) 118 } 119 120 clusterID, err := createResult.Extract() 121 if err != nil { 122 return "", err 123 } 124 125 t.Logf("Cluster created: %+v", clusterID) 126 127 err = WaitForCluster(client, clusterID, "CREATE_COMPLETE") 128 if err != nil { 129 return clusterID, err 130 } 131 132 t.Logf("Successfully created cluster: %s id: %s", clusterName, clusterID) 133 return clusterID, nil 134} 135 136func DeleteCluster(t *testing.T, client *gophercloud.ServiceClient, id string) { 137 t.Logf("Attempting to delete cluster: %s", id) 138 139 r := clusters.Delete(client, id) 140 err := clusters.Delete(client, id).ExtractErr() 141 deleteRequestID := "" 142 idKey := "X-Openstack-Request-Id" 143 if len(r.Header[idKey]) > 0 { 144 deleteRequestID = r.Header[idKey][0] 145 } 146 if err != nil { 147 t.Fatalf("Error deleting cluster. requestID=%s clusterID=%s: err%s:", deleteRequestID, id, err) 148 } 149 150 err = WaitForCluster(client, id, "DELETE_COMPLETE") 151 if err != nil { 152 t.Fatalf("Error deleting cluster %s: %s:", id, err) 153 } 154 155 t.Logf("Successfully deleted cluster: %s", id) 156 157 return 158} 159 160func WaitForCluster(client *gophercloud.ServiceClient, clusterID string, status string) error { 161 return tools.WaitFor(func() (bool, error) { 162 cluster, err := clusters.Get(client, clusterID).Extract() 163 if err != nil { 164 if _, ok := err.(gophercloud.ErrDefault404); ok && status == "DELETE_COMPLETE" { 165 return true, nil 166 } 167 168 return false, err 169 } 170 171 if cluster.Status == status { 172 return true, nil 173 } 174 175 if strings.Contains(cluster.Status, "FAILED") { 176 return false, fmt.Errorf("Cluster %s FAILED. Status=%s StatusReason=%s", clusterID, cluster.Status, cluster.StatusReason) 177 } 178 179 return false, nil 180 }) 181} 182 183// CreateQuota will create a random quota. An error will be returned if the 184// quota could not be created. 185func CreateQuota(t *testing.T, client *gophercloud.ServiceClient) (*quotas.Quotas, error) { 186 name := tools.RandomString("TESTACC-", 8) 187 t.Logf("Attempting to create quota: %s", name) 188 189 idClient, err := clients.NewIdentityV3Client() 190 th.AssertNoErr(t, err) 191 192 project, err := idv3.CreateProject(t, idClient, nil) 193 th.AssertNoErr(t, err) 194 defer idv3.DeleteProject(t, idClient, project.ID) 195 196 createOpts := quotas.CreateOpts{ 197 Resource: "Cluster", 198 ProjectID: project.ID, 199 HardLimit: 10, 200 } 201 202 res := quotas.Create(client, createOpts) 203 if res.Err != nil { 204 return nil, res.Err 205 } 206 207 requestID := res.Header.Get("X-OpenStack-Request-Id") 208 th.AssertEquals(t, true, requestID != "") 209 210 t.Logf("Quota %s request ID: %s", name, requestID) 211 212 quota, err := res.Extract() 213 if err == nil { 214 t.Logf("Successfully created quota: %s", quota.ProjectID) 215 216 tools.PrintResource(t, quota) 217 218 th.AssertEquals(t, project.ID, quota.ProjectID) 219 th.AssertEquals(t, "Cluster", quota.Resource) 220 th.AssertEquals(t, 10, quota.HardLimit) 221 } 222 223 return quota, err 224} 225