Getting Started with Compute v2

Setup

In order to interact with OpenStack APIs, you must first pass in your auth credentials to a Provider struct. Once you have this, you then retrieve whichever service struct you’re interested in - so in our case, we invoke the NewComputeV2 method:

import "github.com/rackspace/gophercloud/openstack"

authOpts, err := openstack.AuthOptionsFromEnv()

provider, err := openstack.AuthenticatedClient(authOpts)

client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{
	Region: "RegionOne",
})

If you’re unsure about how to retrieve credentials, please read our introductory guide which outlines the steps you need to take.

Flavors

A flavor is a hardware configuration for a server. Each one has a unique combination of disk space, memory capacity and priority for CPU time.

List all available flavors

import (
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/openstack/compute/v2/flavors"
)

// We have the option of filtering the flavor list. If we want the full
// collection, leave it as an empty struct
opts := flavors.ListOpts{ChangesSince: "2014-01-01T01:02:03Z", MinRAM: 4}

// Retrieve a pager (i.e. a paginated collection)
pager := flavors.List(client, opts)

// Define an anonymous function to be executed on each page's iteration
err := pager.EachPage(func(page pagination.Page) (bool, error) {
	flavorList, err := networks.ExtractFlavors(page)

	for _, f := range flavorList {
		// "f" will be a flavors.Flavor
	}
})

Get details for a specific flavor

In order to retrieve information for a specific flavor, you need its UUID in string form. You receive back a flavors.Flavor struct with ID, Disk, RAM, Name, RxTxFactor, Swap and VCPUs fields.

// Get back a flavors.Flavor struct
flavor, err := flavors.Get(client, "flavor_id").Extract()

Get a flavor ID from a flavor Name

You can look up the ID of a flavor by using its human-readable name.

// Get back a flavor ID string
flavorID, err := flavors.IDFromName(client, "flavor_name").Extract()

Images

An image is the operating system for a VM - a collection of files used to create or rebuild a server. Operators provide a number of pre-built OS images by default, but you may also create custom images from cloud servers you have launched.

List all available images

import (
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/openstack/compute/v2/images"
)

// We have the option of filtering the image list. If we want the full
// collection, leave it as an empty struct
opts := images.ListOpts{ChangesSince: "2014-01-01T01:02:03Z", Name: "Ubuntu 12.04"}

// Retrieve a pager (i.e. a paginated collection)
pager := images.List(client, opts)

// Define an anonymous function to be executed on each page's iteration
err := pager.EachPage(func(page pagination.Page) (bool, error) {
	imageList, err := images.ExtractImages(page)

	for _, i := range imageList {
		// "i" will be a images.Image
	}
})

Get details for a specific image

In order to retrieve information for a specific flavor, you need its UUID in string form. You receive back an images.Image struct with ID, Created, MinDisk, MinRAM, Name, Progress, Status and Updated fields.

// Get back a images.Image struct
image, err := images.Get(client, "image_id").Extract()

Get an image ID from an image Name

You can look up the ID of an image by using its human-readable name.

// Get back an image ID string
imageID, err := images.IDFromName(client, "image_name").Extract()

Delete an image

res := images.Delete(client, "image_id")

Key Pairs

Create a Key Pair

import (
  "crypto/rand"
  "crypto/rsa"

  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/keypairs"

  "golang.org/x/crypto/ssh"
)

privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
publicKey := privateKey.PublicKey
pub, err := ssh.NewPublicKey(&publicKey)
pubBytes := ssh.MarshalAuthorizedKey(pub)
pk := string(pubBytes)

kp, err := keypairs.Create(client, keypairs.CreateOpts{
  Name:      "keypair_name",
  PublicKey: pk,
}).Extract()

Delete a Key Pair

err := keypairs.Delete(client, "keypair_name").ExtractErr()

Security Groups

Create a Security Group

import (
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
)

opts := secgroups.CreateOpts{
  Name:        "MySecGroup",
  Description: "something",
}

group, err := secgroups.Create(client, opts).Extract()

opts := secgroups.CreateRuleOpts{
  ParentGroupID: group.ID,
  FromPort:      22,
  ToPort:        22,
  IPProtocol:    "TCP",
  CIDR:          "0.0.0.0/0",
}

rule, err := secgroups.CreateRule(client, opts).Extract()

Delete a Security Group

err := secgroups.Delete(client, group.ID).ExtractErr()

Server Groups

Create a Server Group

import (
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups"
)

sg, err := servergroups.Create(computeClient, &servergroups.CreateOpts{
  Name:     "test",
  Policies: []string{"affinity"},
}).Extract()

`Policies` can either be `affinity` or `anti-affinity`.

Delete a Server Group

err := servergroups.Delete(computeClient, "servergroup_id").ExtractErr()

Servers

A server is either a virtual machine (VM) instance or a physical device managed by the compute system.

Create a server

To create a server with a minimal configuration, do:

server, err := servers.Create(client, servers.CreateOpts{
  Name:      name,
  FlavorName: "flavor_name",
  ImageName: "image_name",
}).Extract()
if err != nil {
  fmt.Println("Unable to create server: %s", err)
}
fmt.Println("Server ID: %s", server.ID)

See the Go Documentation for a full list of Create options.

List all available servers

import (
	"github.com/rackspace/gophercloud/pagination"
	"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)

// We have the option of filtering the server list. If we want the full
// collection, leave it as an empty struct
opts := servers.ListOpts{Name: "server_1"}

// Retrieve a pager (i.e. a paginated collection)
pager := servers.List(client, opts)

// Define an anonymous function to be executed on each page's iteration
err := pager.EachPage(func(page pagination.Page) (bool, error) {
	serverList, err := servers.ExtractServers(page)

	for _, s := range serverList {
		// "s" will be a servers.Server
	}
})

Get details for a server

// We need the UUID in string form
server, id := servers.Get(client, "server_id").Extract()

Update an existing server

opts := servers.UpdateOpts{Name: "new_name"}

server, err := servers.Update(client, "server_id", opts).Extract()

Delete an existing server

result := servers.Delete(client, "server_id")

Change admin password

result := servers.ChangeAdminPassword(client, "server_id", "newPassword_&123")

Reboot a server

There are two different methods for rebooting a VM: soft or hard reboot. A soft reboot instructs the operating system to initiate its own restart procedure, whereas a hard reboot cuts power (if a physical machine) or teminates the instance at the hypervisor level (if a virtual machine).

// You have a choice of two reboot methods: servers.SoftReboot or servers.HardReboot
result := servers.Reboot(client, "server_id", servers.SoftReboot)

Rebuild a server

The rebuild operation removes all data on the server and replaces it with the image specified. The server’s existing ID and all IP addresses will remain the same.

// You have the option of specifying additional options
opts := RebuildOpts{
	Name:      "new_name",
	AdminPass: "admin_password",
	ImageID:   "image_id",
	Metadata:  map[string]string{"owner": "me"},
}

result := servers.Rebuild(client, "server_id", opts)

// You can extract a servers.Server struct from the HTTP response
server, err := result.Extract()

Resize a server

result := servers.Resize(client, "server_id", "new_flavor_id")

Confirm a resize operation

result := servers.ConfirmResize(client, "server_id")

Revert a resize operation

result := servers.RevertResize(client, "server_id")

Stop a Server

import (
  "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop"
)

err := startstop.Stop(client, "server_id").ExtractErr()

Start a Server

import (
  "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/startstop"
)

err := startstop.Start(client, "server_id").ExtractErr()

Boot from a Volume

import (
  "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/bootfromvolume"
)

bd := []bootfromvolume.BlockDevice{
  bootfromvolume.BlockDevice{
    UUID:       "image_id",
    SourceType: bootfromvolume.Image,
    VolumeSize: 10,
  },
}

serverCreateOpts := servers.CreateOpts{
  Name:      name,
  FlavorRef: "flavor_id",
}
server, err := bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{
  serverCreateOpts,
  bd,
}).Extract()

Scheduler Hints

import (
  "github.com/rackspace/gophercloud"
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/schedulerhints"
  "github.com/rackspace/gophercloud/openstack/compute/v2/extensions/servergroups"
  "github.com/rackspace/gophercloud/openstack/compute/v2/servers"
)

sg, err := servergroups.Create(computeClient, &servergroups.CreateOpts{
  Name:     "test",
  Policies: []string{"affinity"},
}).Extract()

serverCreateOpts := servers.CreateOpts{
  Name:      name,
  FlavorName: "flavor_name",
  ImageName:  "image_name",
}
server, err := servers.Create(computeClient, schedulerhints.CreateOptsExt{
  serverCreateOpts,
  schedulerhints.SchedulerHints{
    Group: sg.ID,
  },
}).Extract()

More

It’s possible for a new feature or action to be added before the documentation is updated. Check the extensions directory for a full list of Compute extensions.

Providers

Rackspace