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

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