github.com/gophercloud/gophercloud@v1.11.0/internal/acceptance/openstack/orchestration/v1/orchestration.go (about) 1 package v1 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/gophercloud/gophercloud" 8 "github.com/gophercloud/gophercloud/internal/acceptance/tools" 9 "github.com/gophercloud/gophercloud/openstack/orchestration/v1/stacks" 10 th "github.com/gophercloud/gophercloud/testhelper" 11 ) 12 13 const basicTemplateResourceName = "secgroup_1" 14 const basicTemplate = ` 15 { 16 "heat_template_version": "2013-05-23", 17 "description": "Simple template to test heat commands", 18 "resources": { 19 "secgroup_1": { 20 "type": "OS::Neutron::SecurityGroup", 21 "properties": { 22 "description": "Gophercloud test", 23 "name": "secgroup_1" 24 } 25 } 26 } 27 } 28 ` 29 30 const validateTemplate = ` 31 { 32 "heat_template_version": "2013-05-23", 33 "description": "Simple template to test heat commands", 34 "parameters": { 35 "flavor": { 36 "default": "m1.tiny", 37 "type": "string" 38 } 39 }, 40 "resources": { 41 "hello_world": { 42 "type": "OS::Nova::Server", 43 "properties": { 44 "key_name": "heat_key", 45 "flavor": { 46 "get_param": "flavor" 47 }, 48 "image": "ad091b52-742f-469e-8f3c-fd81cadf0743", 49 "user_data": "#!/bin/bash -xv\necho \"hello world\" > /root/hello-world.txt\n" 50 } 51 } 52 } 53 } 54 ` 55 56 // CreateStack will create a heat stack with a randomly generated name. 57 // An error will be returned if the stack failed to be created. 58 func CreateStack(t *testing.T, client *gophercloud.ServiceClient) (*stacks.RetrievedStack, error) { 59 stackName := tools.RandomString("ACCPTEST", 8) 60 t.Logf("Attempting to create stack %s", stackName) 61 62 template := new(stacks.Template) 63 template.Bin = []byte(basicTemplate) 64 65 createOpts := stacks.CreateOpts{ 66 Name: stackName, 67 Timeout: 60, 68 TemplateOpts: template, 69 DisableRollback: gophercloud.Disabled, 70 } 71 72 stack, err := stacks.Create(client, createOpts).Extract() 73 th.AssertNoErr(t, err) 74 75 if err := WaitForStackStatus(client, stackName, stack.ID, "CREATE_COMPLETE"); err != nil { 76 return nil, err 77 } 78 79 newStack, err := stacks.Get(client, stackName, stack.ID).Extract() 80 return newStack, err 81 } 82 83 // DeleteStack deletes a stack via its ID. 84 // A fatal error will occur if the stack failed to be deleted. This works 85 // best when used as a deferred function. 86 func DeleteStack(t *testing.T, client *gophercloud.ServiceClient, stackName, stackID string) { 87 t.Logf("Attempting to delete stack %s (%s)", stackName, stackID) 88 89 err := stacks.Delete(client, stackName, stackID).ExtractErr() 90 if err != nil { 91 t.Fatalf("Failed to delete stack %s: %s", stackID, err) 92 } 93 94 t.Logf("Deleted stack: %s", stackID) 95 } 96 97 // WaitForStackStatus will wait until a stack has reached a certain status. 98 func WaitForStackStatus(client *gophercloud.ServiceClient, stackName, stackID, status string) error { 99 return tools.WaitFor(func() (bool, error) { 100 latest, err := stacks.Get(client, stackName, stackID).Extract() 101 if err != nil { 102 return false, err 103 } 104 105 if latest.Status == status { 106 return true, nil 107 } 108 109 if latest.Status == "ERROR" { 110 return false, fmt.Errorf("Stack in ERROR state") 111 } 112 113 return false, nil 114 }) 115 } 116 117 // CreateStackWithFile will create a heat stack with a randomly generated name that uses get_file. 118 // An error will be returned if the stack failed to be created. 119 func CreateStackWithFile(t *testing.T, client *gophercloud.ServiceClient) (*stacks.RetrievedStack, error) { 120 stackName := tools.RandomString("ACCPTEST", 8) 121 t.Logf("Attempting to create stack %s", stackName) 122 123 template := new(stacks.Template) 124 template.Bin = []byte(`heat_template_version: 2015-04-30 125 resources: 126 test_resource: 127 type: OS::Heat::TestResource 128 properties: 129 value: 130 get_file: testdata/samplefile`) 131 createOpts := stacks.CreateOpts{ 132 Name: stackName, 133 Timeout: 1, 134 TemplateOpts: template, 135 DisableRollback: gophercloud.Disabled, 136 } 137 138 stack, err := stacks.Create(client, createOpts).Extract() 139 th.AssertNoErr(t, err) 140 141 if err := WaitForStackStatus(client, stackName, stack.ID, "CREATE_COMPLETE"); err != nil { 142 return nil, err 143 } 144 145 newStack, err := stacks.Get(client, stackName, stack.ID).Extract() 146 return newStack, err 147 }