func TestStackEvents(t *testing.T) { // Create a provider client for making the HTTP requests. // See common.go in this directory for more information. client := newClient(t) stackName := "postman_stack_2" resourceName := "hello_world" var eventID string createOpts := stacks.CreateOpts{ Name: stackName, Template: template, Timeout: 5, } stack, err := stacks.Create(client, createOpts).Extract() th.AssertNoErr(t, err) t.Logf("Created stack: %+v\n", stack) defer func() { err := stacks.Delete(client, stackName, stack.ID).ExtractErr() th.AssertNoErr(t, err) t.Logf("Deleted stack (%s)", stackName) }() err = gophercloud.WaitFor(60, func() (bool, error) { getStack, err := stacks.Get(client, stackName, stack.ID).Extract() if err != nil { return false, err } if getStack.Status == "CREATE_COMPLETE" { return true, nil } return false, nil }) err = stackevents.List(client, stackName, stack.ID, nil).EachPage(func(page pagination.Page) (bool, error) { events, err := stackevents.ExtractEvents(page) th.AssertNoErr(t, err) t.Logf("listed events: %+v\n", events) eventID = events[0].ID return false, nil }) th.AssertNoErr(t, err) err = stackevents.ListResourceEvents(client, stackName, stack.ID, resourceName, nil).EachPage(func(page pagination.Page) (bool, error) { resourceEvents, err := stackevents.ExtractEvents(page) th.AssertNoErr(t, err) t.Logf("listed resource events: %+v\n", resourceEvents) return false, nil }) th.AssertNoErr(t, err) event, err := stackevents.Get(client, stackName, stack.ID, resourceName, eventID).Extract() th.AssertNoErr(t, err) t.Logf("retrieved event: %+v\n", event) }
func (c context) WaitUntilActive(id string) { err := gophercloud.WaitFor(60, func() (bool, error) { inst, err := instances.Get(c.client, id).Extract() if err != nil { return false, err } if inst.Status == "ACTIVE" { return true, nil } return false, nil }) c.AssertNoErr(err) }
func WaitForPortToCreate(client *gophercloud.ServiceClient, portID string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { p, err := ports.Get(client, portID).Extract() if err != nil { return false, err } if p.Status == "ACTIVE" || p.Status == "DOWN" { return true, nil } return false, nil }) }
// WaitForStatus will continually poll a server until it successfully transitions to a specified // status. It will do this for at most the number of seconds specified. func WaitForStatus(c *gophercloud.ServiceClient, id, status string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { current, err := Get(c, id).Extract() if err != nil { return false, err } if current.Status == status { return true, nil } return false, nil }) }
func WaitForRouterInterfaceToAttach(client *gophercloud.ServiceClient, routerInterfaceID string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { r, err := ports.Get(client, routerInterfaceID).Extract() if err != nil { return false, err } if r.Status == "ACTIVE" { return true, nil } return false, nil }) }
func WaitForRouterToDelete(client *gophercloud.ServiceClient, routerID string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { _, err := routers.Get(client, routerID).Extract() if err != nil { if _, ok := err.(gophercloud.ErrDefault404); ok { return true, nil } return false, err } return false, nil }) }
func TestStackResources(t *testing.T) { // Create a provider client for making the HTTP requests. // See common.go in this directory for more information. client := newClient(t) stackName := "postman_stack_2" createOpts := stacks.CreateOpts{ Name: stackName, Template: template, Timeout: 5, } stack, err := stacks.Create(client, createOpts).Extract() th.AssertNoErr(t, err) t.Logf("Created stack: %+v\n", stack) defer func() { err := stacks.Delete(client, stackName, stack.ID).ExtractErr() th.AssertNoErr(t, err) t.Logf("Deleted stack (%s)", stackName) }() err = gophercloud.WaitFor(60, func() (bool, error) { getStack, err := stacks.Get(client, stackName, stack.ID).Extract() if err != nil { return false, err } if getStack.Status == "CREATE_COMPLETE" { return true, nil } return false, nil }) resourceName := "hello_world" resource, err := stackresources.Get(client, stackName, stack.ID, resourceName).Extract() th.AssertNoErr(t, err) t.Logf("Got stack resource: %+v\n", resource) metadata, err := stackresources.Metadata(client, stackName, stack.ID, resourceName).Extract() th.AssertNoErr(t, err) t.Logf("Got stack resource metadata: %+v\n", metadata) err = stackresources.List(client, stackName, stack.ID, stackresources.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) { resources, err := stackresources.ExtractResources(page) th.AssertNoErr(t, err) t.Logf("resources: %+v\n", resources) return false, nil }) th.AssertNoErr(t, err) }
// WaitForLoadBalancerState will wait until a loadbalancer reaches a given state. func WaitForLoadBalancerState(client *gophercloud.ServiceClient, lbID, status string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { current, err := loadbalancers.Get(client, lbID).Extract() if err != nil { if httpStatus, ok := err.(gophercloud.ErrDefault404); ok { if httpStatus.Actual == 404 { if status == "DELETED" { return true, nil } } } return false, err } if current.ProvisioningStatus == status { return true, nil } return false, nil }) }
// WaitForFirewallState will wait until a firewall reaches a given state. func WaitForFirewallState(client *gophercloud.ServiceClient, firewallID, status string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { current, err := firewalls.Get(client, firewallID).Extract() if err != nil { if httpStatus, ok := err.(gophercloud.ErrDefault404); ok { if httpStatus.Actual == 404 { if status == "DELETED" { return true, nil } } } return false, err } if current.Status == status { return true, nil } return false, nil }) }
// DeleteSnapshot will delete a snapshot. A fatal error will occur if the // snapshot failed to be deleted. This works best when used as a deferred // function. func DeleteSnapshotshot(t *testing.T, client *gophercloud.ServiceClient, snapshot *snapshots.Snapshot) { err := snapshots.Delete(client, snapshot.ID).ExtractErr() if err != nil { t.Fatalf("Unable to delete snapshot %s: %v", snapshot.ID, err) } // Volumes can't be deleted until their snapshots have been, // so block up to 120 seconds for the snapshot to delete. err = gophercloud.WaitFor(120, func() (bool, error) { _, err := snapshots.Get(client, snapshot.ID).Extract() if err != nil { return true, nil } return false, nil }) if err != nil { t.Fatalf("Unable to wait for snapshot to delete: %v", err) } t.Logf("Deleted snapshot: %s", snapshot.ID) }
func WaitForRouterInterfaceToDetach(client *gophercloud.ServiceClient, routerInterfaceID string, secs int) error { return gophercloud.WaitFor(secs, func() (bool, error) { r, err := ports.Get(client, routerInterfaceID).Extract() if err != nil { if _, ok := err.(gophercloud.ErrDefault404); ok { return true, nil } if errCode, ok := err.(gophercloud.ErrUnexpectedResponseCode); ok { if errCode.Actual == 409 { return false, nil } } return false, err } if r.Status == "ACTIVE" { return true, nil } return false, nil }) }
func TestWaitFor(t *testing.T) { err := gophercloud.WaitFor(5, func() (bool, error) { return true, nil }) th.CheckNoErr(t, err) }
// Test using the updated interface func TestStacksNewTemplateFormat(t *testing.T) { // Create a provider client for making the HTTP requests. // See common.go in this directory for more information. client := newClient(t) stackName1 := "gophercloud-test-stack-2" templateOpts := new(osStacks.Template) templateOpts.Bin = []byte(template) createOpts := osStacks.CreateOpts{ Name: stackName1, TemplateOpts: templateOpts, Timeout: 5, } stack, err := stacks.Create(client, createOpts).Extract() th.AssertNoErr(t, err) t.Logf("Created stack: %+v\n", stack) defer func() { err := stacks.Delete(client, stackName1, stack.ID).ExtractErr() th.AssertNoErr(t, err) t.Logf("Deleted stack (%s)", stackName1) }() err = gophercloud.WaitFor(60, func() (bool, error) { getStack, err := stacks.Get(client, stackName1, stack.ID).Extract() if err != nil { return false, err } if getStack.Status == "CREATE_COMPLETE" { return true, nil } return false, nil }) updateOpts := osStacks.UpdateOpts{ TemplateOpts: templateOpts, Timeout: 20, } err = stacks.Update(client, stackName1, stack.ID, updateOpts).ExtractErr() th.AssertNoErr(t, err) err = gophercloud.WaitFor(60, func() (bool, error) { getStack, err := stacks.Get(client, stackName1, stack.ID).Extract() if err != nil { return false, err } if getStack.Status == "UPDATE_COMPLETE" { return true, nil } return false, nil }) t.Logf("Updated stack") err = stacks.List(client, nil).EachPage(func(page pagination.Page) (bool, error) { stackList, err := osStacks.ExtractStacks(page) th.AssertNoErr(t, err) t.Logf("Got stack list: %+v\n", stackList) return true, nil }) th.AssertNoErr(t, err) getStack, err := stacks.Get(client, stackName1, stack.ID).Extract() th.AssertNoErr(t, err) t.Logf("Got stack: %+v\n", getStack) abandonedStack, err := stacks.Abandon(client, stackName1, stack.ID).Extract() th.AssertNoErr(t, err) t.Logf("Abandonded stack %+v\n", abandonedStack) th.AssertNoErr(t, err) }
func TestStackTemplates(t *testing.T) { // Create a provider client for making the HTTP requests. // See common.go in this directory for more information. client := newClient(t) stackName := "postman_stack_2" createOpts := stacks.CreateOpts{ Name: stackName, Template: template, Timeout: 5, } stack, err := stacks.Create(client, createOpts).Extract() th.AssertNoErr(t, err) t.Logf("Created stack: %+v\n", stack) defer func() { err := stacks.Delete(client, stackName, stack.ID).ExtractErr() th.AssertNoErr(t, err) t.Logf("Deleted stack (%s)", stackName) }() err = gophercloud.WaitFor(60, func() (bool, error) { getStack, err := stacks.Get(client, stackName, stack.ID).Extract() if err != nil { return false, err } if getStack.Status == "CREATE_COMPLETE" { return true, nil } return false, nil }) tmpl, err := stacktemplates.Get(client, stackName, stack.ID).Extract() th.AssertNoErr(t, err) t.Logf("retrieved template: %+v\n", tmpl) validateOpts := osStacktemplates.ValidateOpts{ Template: `{"heat_template_version": "2013-05-23", "description": "Simple template to test heat commands", "parameters": { "flavor": { "default": "m1.tiny", "type": "string", }, }, "resources": { "hello_world": { "type": "OS::Nova::Server", "properties": { "key_name": "heat_key", "flavor": { "get_param": "flavor", }, "image": "ad091b52-742f-469e-8f3c-fd81cadf0743", "user_data": "#!/bin/bash -xv\necho \"hello world\" > /root/hello-world.txt\n", }, }, }, }`} validatedTemplate, err := stacktemplates.Validate(client, validateOpts).Extract() th.AssertNoErr(t, err) t.Logf("validated template: %+v\n", validatedTemplate) }