diff --git a/acceptance/openstack/compute/v2/compute.go b/acceptance/openstack/compute/v2/compute.go
new file mode 100644
index 0000000..80bdf86
--- /dev/null
+++ b/acceptance/openstack/compute/v2/compute.go
@@ -0,0 +1,773 @@
+// Package v2 contains common functions for creating compute-based resources
+// for use in acceptance tests. See the `*_test.go` files for example usages.
+package v2
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"fmt"
+	"testing"
+
+	"github.com/gophercloud/gophercloud"
+	"github.com/gophercloud/gophercloud/acceptance/clients"
+	"github.com/gophercloud/gophercloud/acceptance/tools"
+	"github.com/gophercloud/gophercloud/openstack/blockstorage/v1/volumes"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/bootfromvolume"
+	dsr "github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/defsecrules"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/floatingips"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/networks"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/quotasets"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/schedulerhints"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/servergroups"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/tenantnetworks"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/volumeattach"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/images"
+	"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
+
+	"golang.org/x/crypto/ssh"
+)
+
+// AssociateFloatingIP will associate a floating IP with an instance. An error
+// will be returned if the floating IP was unable to be associated.
+func AssociateFloatingIP(t *testing.T, client *gophercloud.ServiceClient, floatingIP *floatingips.FloatingIP, server *servers.Server) error {
+	associateOpts := floatingips.AssociateOpts{
+		FloatingIP: floatingIP.IP,
+	}
+
+	t.Logf("Attempting to associate floating IP %s to instance %s", floatingIP.IP, server.ID)
+	err := floatingips.AssociateInstance(client, server.ID, associateOpts).ExtractErr()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// AssociateFloatingIPWithFixedIP will associate a floating IP with an
+// instance's specific fixed IP. An error will be returend if the floating IP
+// was unable to be associated.
+func AssociateFloatingIPWithFixedIP(t *testing.T, client *gophercloud.ServiceClient, floatingIP *floatingips.FloatingIP, server *servers.Server, fixedIP string) error {
+	associateOpts := floatingips.AssociateOpts{
+		FloatingIP: floatingIP.IP,
+		FixedIP:    fixedIP,
+	}
+
+	t.Logf("Attempting to associate floating IP %s to fixed IP %s on instance %s", floatingIP.IP, fixedIP, server.ID)
+	err := floatingips.AssociateInstance(client, server.ID, associateOpts).ExtractErr()
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// CreateBootableVolumeServer works like CreateServer but is configured with
+// one or more block devices defined by passing in []bootfromvolume.BlockDevice.
+// An error will be returned if a server was unable to be created.
+func CreateBootableVolumeServer(t *testing.T, client *gophercloud.ServiceClient, blockDevices []bootfromvolume.BlockDevice, choices *clients.AcceptanceTestChoices) (*servers.Server, error) {
+	if testing.Short() {
+		t.Skip("Skipping test that requires server creation in short mode.")
+	}
+
+	var server *servers.Server
+
+	networkID, err := GetNetworkIDFromTenantNetworks(t, client, choices.NetworkName)
+	if err != nil {
+		return server, err
+	}
+
+	name := tools.RandomString("ACPTTEST", 16)
+	t.Logf("Attempting to create bootable volume server: %s", name)
+
+	serverCreateOpts := servers.CreateOpts{
+		Name:      name,
+		FlavorRef: choices.FlavorID,
+		ImageRef:  choices.ImageID,
+		Networks: []servers.Network{
+			servers.Network{UUID: networkID},
+		},
+	}
+
+	server, err = bootfromvolume.Create(client, bootfromvolume.CreateOptsExt{
+		serverCreateOpts,
+		blockDevices,
+	}).Extract()
+
+	if err != nil {
+		return server, err
+	}
+
+	return server, nil
+}
+
+// CreateDefaultRule will create a default security group rule with a
+// random port range between 80 and 90. An error will be returned if
+// a default rule was unable to be created.
+func CreateDefaultRule(t *testing.T, client *gophercloud.ServiceClient) (dsr.DefaultRule, error) {
+	createOpts := dsr.CreateOpts{
+		FromPort:   tools.RandomInt(80, 89),
+		ToPort:     tools.RandomInt(90, 99),
+		IPProtocol: "TCP",
+		CIDR:       "0.0.0.0/0",
+	}
+
+	defaultRule, err := dsr.Create(client, createOpts).Extract()
+	if err != nil {
+		return *defaultRule, err
+	}
+
+	t.Logf("Created default rule: %s", defaultRule.ID)
+
+	return *defaultRule, nil
+}
+
+// CreateFloatingIP will allocate a floating IP.
+// An error will be returend if one was unable to be allocated.
+func CreateFloatingIP(t *testing.T, client *gophercloud.ServiceClient, choices *clients.AcceptanceTestChoices) (*floatingips.FloatingIP, error) {
+	createOpts := floatingips.CreateOpts{
+		Pool: choices.FloatingIPPoolName,
+	}
+	floatingIP, err := floatingips.Create(client, createOpts).Extract()
+	if err != nil {
+		return floatingIP, err
+	}
+
+	t.Logf("Created floating IP: %s", floatingIP.ID)
+	return floatingIP, nil
+}
+
+func createKey() (string, error) {
+	privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		return "", err
+	}
+
+	publicKey := privateKey.PublicKey
+	pub, err := ssh.NewPublicKey(&publicKey)
+	if err != nil {
+		return "", err
+	}
+
+	pubBytes := ssh.MarshalAuthorizedKey(pub)
+	pk := string(pubBytes)
+	return pk, nil
+}
+
+// CreateKeyPair will create a KeyPair with a random name. An error will occur
+// if the keypair failed to be created. An error will be returned if the
+// keypair was unable to be created.
+func CreateKeyPair(t *testing.T, client *gophercloud.ServiceClient) (*keypairs.KeyPair, error) {
+	keyPairName := tools.RandomString("keypair_", 5)
+
+	t.Logf("Attempting to create keypair: %s", keyPairName)
+	createOpts := keypairs.CreateOpts{
+		Name: keyPairName,
+	}
+	keyPair, err := keypairs.Create(client, createOpts).Extract()
+	if err != nil {
+		return keyPair, err
+	}
+
+	t.Logf("Created keypair: %s", keyPairName)
+	return keyPair, nil
+}
+
+// CreateSecurityGroup will create a security group with a random name.
+// An error will be returned if one was failed to be created.
+func CreateSecurityGroup(t *testing.T, client *gophercloud.ServiceClient) (secgroups.SecurityGroup, error) {
+	createOpts := secgroups.CreateOpts{
+		Name:        tools.RandomString("secgroup_", 5),
+		Description: "something",
+	}
+
+	securityGroup, err := secgroups.Create(client, createOpts).Extract()
+	if err != nil {
+		return *securityGroup, err
+	}
+
+	t.Logf("Created security group: %s", securityGroup.ID)
+	return *securityGroup, nil
+}
+
+// CreateSecurityGroupRule will create a security group rule with a random name
+// and a random TCP port range between port 80 and 99. An error will be
+// returned if the rule failed to be created.
+func CreateSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, securityGroupID string) (secgroups.Rule, error) {
+	createOpts := secgroups.CreateRuleOpts{
+		ParentGroupID: securityGroupID,
+		FromPort:      tools.RandomInt(80, 89),
+		ToPort:        tools.RandomInt(90, 99),
+		IPProtocol:    "TCP",
+		CIDR:          "0.0.0.0/0",
+	}
+
+	rule, err := secgroups.CreateRule(client, createOpts).Extract()
+	if err != nil {
+		return *rule, err
+	}
+
+	t.Logf("Created security group rule: %s", rule.ID)
+	return *rule, nil
+}
+
+// CreateServer creates a basic instance with a randomly generated name.
+// The flavor of the instance will be the value of the OS_FLAVOR_ID environment variable.
+// The image will be the value of the OS_IMAGE_ID environment variable.
+// The instance will be launched on the network specified in OS_NETWORK_NAME.
+// An error will be returned if the instance was unable to be created.
+func CreateServer(t *testing.T, client *gophercloud.ServiceClient, choices *clients.AcceptanceTestChoices) (*servers.Server, error) {
+	if testing.Short() {
+		t.Skip("Skipping test that requires server creation in short mode.")
+	}
+
+	var server *servers.Server
+
+	networkID, err := GetNetworkIDFromTenantNetworks(t, client, choices.NetworkName)
+	if err != nil {
+		return server, err
+	}
+
+	name := tools.RandomString("ACPTTEST", 16)
+	t.Logf("Attempting to create server: %s", name)
+
+	pwd := tools.MakeNewPassword("")
+
+	server, err = servers.Create(client, servers.CreateOpts{
+		Name:      name,
+		FlavorRef: choices.FlavorID,
+		ImageRef:  choices.ImageID,
+		AdminPass: pwd,
+		Networks: []servers.Network{
+			servers.Network{UUID: networkID},
+		},
+		Personality: servers.Personality{
+			&servers.File{
+				Path:     "/etc/test",
+				Contents: []byte("hello world"),
+			},
+		},
+	}).Extract()
+	if err != nil {
+		return server, err
+	}
+
+	if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil {
+		return server, err
+	}
+
+	return server, nil
+}
+
+// CreateServerGroup will create a server with a random name. An error will be
+// returned if the server group failed to be created.
+func CreateServerGroup(t *testing.T, client *gophercloud.ServiceClient, policy string) (*servergroups.ServerGroup, error) {
+	sg, err := servergroups.Create(client, &servergroups.CreateOpts{
+		Name:     "test",
+		Policies: []string{policy},
+	}).Extract()
+
+	if err != nil {
+		return sg, err
+	}
+
+	return sg, nil
+}
+
+// CreateServerInServerGroup works like CreateServer but places the instance in
+// a specified Server Group.
+func CreateServerInServerGroup(t *testing.T, client *gophercloud.ServiceClient, choices *clients.AcceptanceTestChoices, serverGroup *servergroups.ServerGroup) (*servers.Server, error) {
+	if testing.Short() {
+		t.Skip("Skipping test that requires server creation in short mode.")
+	}
+
+	var server *servers.Server
+
+	networkID, err := GetNetworkIDFromTenantNetworks(t, client, choices.NetworkName)
+	if err != nil {
+		return server, err
+	}
+
+	name := tools.RandomString("ACPTTEST", 16)
+	t.Logf("Attempting to create server: %s", name)
+
+	pwd := tools.MakeNewPassword("")
+
+	serverCreateOpts := servers.CreateOpts{
+		Name:      name,
+		FlavorRef: choices.FlavorID,
+		ImageRef:  choices.ImageID,
+		AdminPass: pwd,
+		Networks: []servers.Network{
+			servers.Network{UUID: networkID},
+		},
+	}
+
+	schedulerHintsOpts := schedulerhints.CreateOptsExt{
+		serverCreateOpts,
+		schedulerhints.SchedulerHints{
+			Group: serverGroup.ID,
+		},
+	}
+	server, err = servers.Create(client, schedulerHintsOpts).Extract()
+	if err != nil {
+		return server, err
+	}
+
+	return server, nil
+}
+
+// CreateServerWithPublicKey works the same as CreateServer, but additionally
+// configures the server with a specified Key Pair name.
+func CreateServerWithPublicKey(t *testing.T, client *gophercloud.ServiceClient, choices *clients.AcceptanceTestChoices, keyPairName string) (*servers.Server, error) {
+	if testing.Short() {
+		t.Skip("Skipping test that requires server creation in short mode.")
+	}
+
+	var server *servers.Server
+
+	networkID, err := GetNetworkIDFromTenantNetworks(t, client, choices.NetworkName)
+	if err != nil {
+		return server, err
+	}
+
+	name := tools.RandomString("ACPTTEST", 16)
+	t.Logf("Attempting to create server: %s", name)
+
+	serverCreateOpts := servers.CreateOpts{
+		Name:      name,
+		FlavorRef: choices.FlavorID,
+		ImageRef:  choices.ImageID,
+		Networks: []servers.Network{
+			servers.Network{UUID: networkID},
+		},
+	}
+
+	server, err = servers.Create(client, keypairs.CreateOptsExt{
+		serverCreateOpts,
+		keyPairName,
+	}).Extract()
+	if err != nil {
+		return server, err
+	}
+
+	if err = WaitForComputeStatus(client, server, "ACTIVE"); err != nil {
+		return server, err
+	}
+
+	return server, nil
+}
+
+// CreateVolumeAttachment will attach a volume to a servert. An error will be
+// returned if the volume failed to attach.
+func CreateVolumeAttachment(t *testing.T, client *gophercloud.ServiceClient, blockClient *gophercloud.ServiceClient, server *servers.Server, volume *volumes.Volume) (*volumeattach.VolumeAttachment, error) {
+	volumeAttachOptions := volumeattach.CreateOpts{
+		VolumeID: volume.ID,
+	}
+
+	t.Logf("Attempting to attach volume %s to server %s", volume.ID, server.ID)
+	volumeAttachment, err := volumeattach.Create(client, server.ID, volumeAttachOptions).Extract()
+	if err != nil {
+		return volumeAttachment, err
+	}
+
+	if err = volumes.WaitForStatus(blockClient, volume.ID, "in-use", 60); err != nil {
+		return volumeAttachment, err
+	}
+
+	return volumeAttachment, nil
+}
+
+// DeleteDefaultRule deletes a default security group rule.
+// A fatal error will occur if the rule failed to delete. This works best when
+// using it as a deferred function.
+func DeleteDefaultRule(t *testing.T, client *gophercloud.ServiceClient, defaultRule dsr.DefaultRule) {
+	err := dsr.Delete(client, defaultRule.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete default rule %s: %v", defaultRule.ID, err)
+	}
+
+	t.Logf("Deleted default rule: %s", defaultRule.ID)
+}
+
+// DeleteFloatingIP will de-allocate a floating IP. A fatal error will occur if
+// the floating IP failed to de-allocate. This works best when using it as a
+// deferred function.
+func DeleteFloatingIP(t *testing.T, client *gophercloud.ServiceClient, floatingIP *floatingips.FloatingIP) {
+	err := floatingips.Delete(client, floatingIP.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete floating IP %s: %v", floatingIP.ID, err)
+	}
+
+	t.Logf("Deleted floating IP: %s", floatingIP.ID)
+}
+
+// DeleteKeyPair will delete a specified keypair. A fatal error will occur if
+// the keypair failed to be deleted. This works best when used as a deferred
+// function.
+func DeleteKeyPair(t *testing.T, client *gophercloud.ServiceClient, keyPair *keypairs.KeyPair) {
+	err := keypairs.Delete(client, keyPair.Name).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete keypair %s: %v", keyPair.Name, err)
+	}
+
+	t.Logf("Deleted keypair: %s", keyPair.Name)
+}
+
+// DeleteSecurityGroup will delete a security group. A fatal error will occur
+// if the group failed to be deleted. This works best as a deferred function.
+func DeleteSecurityGroup(t *testing.T, client *gophercloud.ServiceClient, securityGroup secgroups.SecurityGroup) {
+	err := secgroups.Delete(client, securityGroup.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete security group %s: %s", securityGroup.ID, err)
+	}
+
+	t.Logf("Deleted security group: %s", securityGroup.ID)
+}
+
+// DeleteSecurityGroupRule will delete a security group rule. A fatal error
+// will occur if the rule failed to be deleted. This works best when used
+// as a deferred function.
+func DeleteSecurityGroupRule(t *testing.T, client *gophercloud.ServiceClient, rule secgroups.Rule) {
+	err := secgroups.DeleteRule(client, rule.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete rule: %v", err)
+	}
+
+	t.Logf("Deleted security group rule: %s", rule.ID)
+}
+
+// DeleteServer deletes an instance via its UUID.
+// A fatal error will occur if the instance failed to be destroyed. This works
+// best when using it as a deferred function.
+func DeleteServer(t *testing.T, client *gophercloud.ServiceClient, server *servers.Server) {
+	err := servers.Delete(client, server.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete server %s: %s", server.ID, err)
+	}
+
+	t.Logf("Deleted server: %s", server.ID)
+}
+
+// DeleteServerGroup will delete a server group. A fatal error will occur if
+// the server group failed to be deleted. This works best when used as a
+// deferred function.
+func DeleteServerGroup(t *testing.T, client *gophercloud.ServiceClient, serverGroup *servergroups.ServerGroup) {
+	err := servergroups.Delete(client, serverGroup.ID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to delete server group %s: %v", serverGroup.ID, err)
+	}
+
+	t.Logf("Deleted server group %s", serverGroup.ID)
+}
+
+// DeleteVolumeAttachment will disconnect a volume from an instance. A fatal
+// error will occur if the volume failed to detach. This works best when used
+// as a deferred functino.
+func DeleteVolumeAttachment(t *testing.T, client *gophercloud.ServiceClient, blockClient *gophercloud.ServiceClient, server *servers.Server, volumeAttachment *volumeattach.VolumeAttachment) {
+
+	err := volumeattach.Delete(client, server.ID, volumeAttachment.VolumeID).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to detach volume: %v", err)
+	}
+
+	if err = volumes.WaitForStatus(blockClient, volumeAttachment.ID, "available", 60); err != nil {
+		t.Fatalf("Unable to wait for volume: %v", err)
+	}
+	t.Logf("Deleted volume: %s", volumeAttachment.VolumeID)
+}
+
+// DisassociateFloatingIP will disassociate a floating IP from an instance. A
+// fatal error will occur if the floating IP failed to disassociate. This works
+// best when using it as a deferred function.
+func DisassociateFloatingIP(t *testing.T, client *gophercloud.ServiceClient, floatingIP *floatingips.FloatingIP, server *servers.Server) {
+	disassociateOpts := floatingips.DisassociateOpts{
+		FloatingIP: floatingIP.IP,
+	}
+
+	err := floatingips.DisassociateInstance(client, server.ID, disassociateOpts).ExtractErr()
+	if err != nil {
+		t.Fatalf("Unable to disassociate floating IP %s from server %s: %v", floatingIP.IP, server.ID, err)
+	}
+
+	t.Logf("Disassociated floating IP %s from server %s", floatingIP.IP, server.ID)
+}
+
+// GetNetworkIDFromNetworks will return the network ID from a specified network
+// UUID using the os-networks API extension. An error will be returned if the
+// network could not be retrieved.
+func GetNetworkIDFromNetworks(t *testing.T, client *gophercloud.ServiceClient, networkName string) (string, error) {
+	allPages, err := networks.List(client).AllPages()
+	if err != nil {
+		t.Fatalf("Unable to list networks: %v", err)
+	}
+
+	networkList, err := networks.ExtractNetworks(allPages)
+	if err != nil {
+		t.Fatalf("Unable to list networks: %v", err)
+	}
+
+	networkID := ""
+	for _, network := range networkList {
+		t.Logf("Network: %v", network)
+		if network.Label == networkName {
+			networkID = network.ID
+		}
+	}
+
+	t.Logf("Found network ID for %s: %s", networkName, networkID)
+
+	return networkID, nil
+}
+
+// GetNetworkIDFromTenantNetworks will return the network UUID for a given
+// network name using the os-tenant-networks API extension. An error will be
+// returned if the network could not be retrieved.
+func GetNetworkIDFromTenantNetworks(t *testing.T, client *gophercloud.ServiceClient, networkName string) (string, error) {
+	allPages, err := tenantnetworks.List(client).AllPages()
+	if err != nil {
+		return "", err
+	}
+
+	allTenantNetworks, err := tenantnetworks.ExtractNetworks(allPages)
+	if err != nil {
+		return "", err
+	}
+
+	for _, network := range allTenantNetworks {
+		if network.Name == networkName {
+			return network.ID, nil
+		}
+	}
+
+	return "", fmt.Errorf("Failed to obtain network ID for network %s", networkName)
+}
+
+// ImportPublicKey will create a KeyPair with a random name and a specified
+// public key. An error will be returned if the keypair failed to be created.
+func ImportPublicKey(t *testing.T, client *gophercloud.ServiceClient, publicKey string) (*keypairs.KeyPair, error) {
+	keyPairName := tools.RandomString("keypair_", 5)
+
+	t.Logf("Attempting to create keypair: %s", keyPairName)
+	createOpts := keypairs.CreateOpts{
+		Name:      keyPairName,
+		PublicKey: publicKey,
+	}
+	keyPair, err := keypairs.Create(client, createOpts).Extract()
+	if err != nil {
+		return keyPair, err
+	}
+
+	t.Logf("Created keypair: %s", keyPairName)
+	return keyPair, nil
+}
+
+// ResizeServer performs a resize action on an instance. An error will be
+// returned if the instance failed to resize.
+// The new flavor that the instance will be resized to is specified in OS_FLAVOR_ID_RESIZE.
+func ResizeServer(t *testing.T, client *gophercloud.ServiceClient, server *servers.Server, choices *clients.AcceptanceTestChoices) error {
+	opts := &servers.ResizeOpts{
+		FlavorRef: choices.FlavorIDResize,
+	}
+	if res := servers.Resize(client, server.ID, opts); res.Err != nil {
+		return res.Err
+	}
+
+	if err := WaitForComputeStatus(client, server, "VERIFY_RESIZE"); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// WaitForComputeStatus will poll an instance's status until it either matches
+// the specified status or the status becomes ERROR.
+func WaitForComputeStatus(client *gophercloud.ServiceClient, server *servers.Server, status string) error {
+	return tools.WaitFor(func() (bool, error) {
+		latest, err := servers.Get(client, server.ID).Extract()
+		if err != nil {
+			return false, err
+		}
+
+		if latest.Status == status {
+			// Success!
+			return true, nil
+		}
+
+		if latest.Status == "ERROR" {
+			return false, fmt.Errorf("Instance in ERROR state")
+		}
+
+		return false, nil
+	})
+}
+
+// PrintServer will print an instance and all of its attributes.
+func PrintServer(t *testing.T, server *servers.Server) {
+	t.Logf("ID: %s", server.ID)
+	t.Logf("TenantID: %s", server.TenantID)
+	t.Logf("UserID: %s", server.UserID)
+	t.Logf("Name: %s", server.Name)
+	t.Logf("Updated: %s", server.Updated)
+	t.Logf("Created: %s", server.Created)
+	t.Logf("HostID: %s", server.HostID)
+	t.Logf("Status: %s", server.Status)
+	t.Logf("Progress: %d", server.Progress)
+	t.Logf("AccessIPv4: %s", server.AccessIPv4)
+	t.Logf("AccessIPv6: %s", server.AccessIPv6)
+	t.Logf("Image: %s", server.Image)
+	t.Logf("Flavor: %s", server.Flavor)
+	t.Logf("Addresses: %#v", server.Addresses)
+	t.Logf("Metadata: %#v", server.Metadata)
+	t.Logf("Links: %#v", server.Links)
+	t.Logf("KeyName: %s", server.KeyName)
+	t.Logf("AdminPass: %s", server.AdminPass)
+	t.Logf("SecurityGroups: %#v", server.SecurityGroups)
+}
+
+// PrintDefaultRule will print a default security group rule and all of its attributes.
+func PrintDefaultRule(t *testing.T, defaultRule *dsr.DefaultRule) {
+	t.Logf("\tID: %s", defaultRule.ID)
+	t.Logf("\tFrom Port: %d", defaultRule.FromPort)
+	t.Logf("\tTo Port: %d", defaultRule.ToPort)
+	t.Logf("\tIP Protocol: %s", defaultRule.IPProtocol)
+	t.Logf("\tIP Range: %s", defaultRule.IPRange.CIDR)
+	t.Logf("\tParent Group ID: %s", defaultRule.ParentGroupID)
+	t.Logf("\tGroup Tenant ID: %s", defaultRule.Group.TenantID)
+	t.Logf("\tGroup Name: %s", defaultRule.Group.Name)
+}
+
+// PrintFlavor will print a flavor and all of its attributes.
+func PrintFlavor(t *testing.T, flavor *flavors.Flavor) {
+	t.Logf("ID: %s", flavor.ID)
+	t.Logf("Name: %s", flavor.Name)
+	t.Logf("RAM: %d", flavor.RAM)
+	t.Logf("Disk: %d", flavor.Disk)
+	t.Logf("Swap: %d", flavor.Swap)
+	t.Logf("RxTxFactor: %f", flavor.RxTxFactor)
+}
+
+// PrintFloatingIP will print a floating IP and all of its attributes.
+func PrintFloatingIP(t *testing.T, floatingIP *floatingips.FloatingIP) {
+	t.Logf("ID: %s", floatingIP.ID)
+	t.Logf("Fixed IP: %s", floatingIP.FixedIP)
+	t.Logf("Instance ID: %s", floatingIP.InstanceID)
+	t.Logf("IP: %s", floatingIP.IP)
+	t.Logf("Pool: %s", floatingIP.Pool)
+}
+
+// PrintImage will print an image and all of its attributes.
+func PrintImage(t *testing.T, image images.Image) {
+	t.Logf("ID: %s", image.ID)
+	t.Logf("Name: %s", image.Name)
+	t.Logf("MinDisk: %d", image.MinDisk)
+	t.Logf("MinRAM: %d", image.MinRAM)
+	t.Logf("Status: %s", image.Status)
+	t.Logf("Progress: %d", image.Progress)
+	t.Logf("Metadata: %#v", image.Metadata)
+	t.Logf("Created: %s", image.Created)
+	t.Logf("Updated: %s", image.Updated)
+}
+
+// PrintKeyPair will print keypair and all of its attributes.
+func PrintKeyPair(t *testing.T, keypair *keypairs.KeyPair) {
+	t.Logf("Name: %s", keypair.Name)
+	t.Logf("Fingerprint: %s", keypair.Fingerprint)
+	t.Logf("Public Key: %s", keypair.PublicKey)
+	t.Logf("Private Key: %s", keypair.PrivateKey)
+	t.Logf("UserID: %s", keypair.UserID)
+}
+
+//  PrintNetwork will print an os-networks based network and all of its attributes.
+func PrintNetwork(t *testing.T, network *networks.Network) {
+	t.Logf("Bridge: %s", network.Bridge)
+	t.Logf("BridgeInterface: %s", network.BridgeInterface)
+	t.Logf("Broadcast: %s", network.Broadcast)
+	t.Logf("CIDR: %s", network.CIDR)
+	t.Logf("CIDRv6: %s", network.CIDRv6)
+	t.Logf("CreatedAt: %v", network.CreatedAt)
+	t.Logf("Deleted: %t", network.Deleted)
+	t.Logf("DeletedAt: %v", network.DeletedAt)
+	t.Logf("DHCPStart: %s", network.DHCPStart)
+	t.Logf("DNS1: %s", network.DNS1)
+	t.Logf("DNS2: %s", network.DNS2)
+	t.Logf("Gateway: %s", network.Gateway)
+	t.Logf("Gatewayv6: %s", network.Gatewayv6)
+	t.Logf("Host: %s", network.Host)
+	t.Logf("ID: %s", network.ID)
+	t.Logf("Injected: %t", network.Injected)
+	t.Logf("Label: %s", network.Label)
+	t.Logf("MultiHost: %t", network.MultiHost)
+	t.Logf("Netmask: %s", network.Netmask)
+	t.Logf("Netmaskv6: %s", network.Netmaskv6)
+	t.Logf("Priority: %d", network.Priority)
+	t.Logf("ProjectID: %s", network.ProjectID)
+	t.Logf("RXTXBase: %d", network.RXTXBase)
+	t.Logf("UpdatedAt: %v", network.UpdatedAt)
+	t.Logf("VLAN: %d", network.VLAN)
+	t.Logf("VPNPrivateAddress: %s", network.VPNPrivateAddress)
+	t.Logf("VPNPublicAddress: %s", network.VPNPublicAddress)
+	t.Logf("VPNPublicPort: %d", network.VPNPublicPort)
+}
+
+//  PrintQuotaSet will print a quota set and all of its attributes.
+func PrintQuotaSet(t *testing.T, quotaSet *quotasets.QuotaSet) {
+	t.Logf("instances: %d\n", quotaSet.Instances)
+	t.Logf("cores: %d\n", quotaSet.Cores)
+	t.Logf("ram: %d\n", quotaSet.Ram)
+	t.Logf("key_pairs: %d\n", quotaSet.KeyPairs)
+	t.Logf("metadata_items: %d\n", quotaSet.MetadataItems)
+	t.Logf("security_groups: %d\n", quotaSet.SecurityGroups)
+	t.Logf("security_group_rules: %d\n", quotaSet.SecurityGroupRules)
+	t.Logf("fixed_ips: %d\n", quotaSet.FixedIps)
+	t.Logf("floating_ips: %d\n", quotaSet.FloatingIps)
+	t.Logf("injected_file_content_bytes: %d\n", quotaSet.InjectedFileContentBytes)
+	t.Logf("injected_file_path_bytes: %d\n", quotaSet.InjectedFilePathBytes)
+	t.Logf("injected_files: %d\n", quotaSet.InjectedFiles)
+}
+
+//  PrintSecurityGroup will print a security group and all of its attributes and rules.
+func PrintSecurityGroup(t *testing.T, securityGroup *secgroups.SecurityGroup) {
+	t.Logf("ID: %s", securityGroup.ID)
+	t.Logf("Name: %s", securityGroup.Name)
+	t.Logf("Description: %s", securityGroup.Description)
+	t.Logf("Tenant ID: %s", securityGroup.TenantID)
+	t.Logf("Rules:")
+
+	for _, rule := range securityGroup.Rules {
+		t.Logf("\tID: %s", rule.ID)
+		t.Logf("\tFrom Port: %d", rule.FromPort)
+		t.Logf("\tTo Port: %d", rule.ToPort)
+		t.Logf("\tIP Protocol: %s", rule.IPProtocol)
+		t.Logf("\tIP Range: %s", rule.IPRange.CIDR)
+		t.Logf("\tParent Group ID: %s", rule.ParentGroupID)
+		t.Logf("\tGroup Tenant ID: %s", rule.Group.TenantID)
+		t.Logf("\tGroup Name: %s", rule.Group.Name)
+	}
+}
+
+// PrintServerGroup will print a server group and all of its attributes.
+func PrintServerGroup(t *testing.T, serverGroup *servergroups.ServerGroup) {
+	t.Logf("ID: %s", serverGroup.ID)
+	t.Logf("Name: %s", serverGroup.Name)
+	t.Logf("Policies: %#v", serverGroup.Policies)
+	t.Logf("Members: %#v", serverGroup.Members)
+	t.Logf("Metadata: %#v", serverGroup.Metadata)
+}
+
+// PrintTenantNetwork will print an os-tenant-networks based network and all of its attributes.
+func PrintTenantNetwork(t *testing.T, network *tenantnetworks.Network) {
+	t.Logf("ID: %s", network.ID)
+	t.Logf("Name: %s", network.Name)
+	t.Logf("CIDR: %s", network.CIDR)
+}
+
+// PrintVolumeAttachment will print a volume attachment and all of its attributes.
+func PrintVolumeAttachment(t *testing.T, volumeAttachment *volumeattach.VolumeAttachment) {
+	t.Logf("ID: %s", volumeAttachment.ID)
+	t.Logf("Device: %s", volumeAttachment.Device)
+	t.Logf("VolumeID: %s", volumeAttachment.VolumeID)
+	t.Logf("ServerID: %s", volumeAttachment.ServerID)
+}
