github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/builtin/providers/openstack/resource_openstack_compute_instance_v2_test.go (about)

     1  package openstack
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/terraform/helper/resource"
     9  	"github.com/hashicorp/terraform/terraform"
    10  
    11  	"github.com/rackspace/gophercloud/openstack/blockstorage/v1/volumes"
    12  	"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/floatingip"
    13  	"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
    14  	"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/volumeattach"
    15  	"github.com/rackspace/gophercloud/openstack/compute/v2/servers"
    16  	"github.com/rackspace/gophercloud/pagination"
    17  )
    18  
    19  func TestAccComputeV2Instance_basic(t *testing.T) {
    20  	var instance servers.Server
    21  	var testAccComputeV2Instance_basic = fmt.Sprintf(`
    22  		resource "openstack_compute_instance_v2" "foo" {
    23  			name = "terraform-test"
    24  			security_groups = ["default"]
    25  			network {
    26  				uuid = "%s"
    27  			}
    28  			metadata {
    29  				foo = "bar"
    30  			}
    31  		}`,
    32  		os.Getenv("OS_NETWORK_ID"))
    33  
    34  	resource.Test(t, resource.TestCase{
    35  		PreCheck:     func() { testAccPreCheck(t) },
    36  		Providers:    testAccProviders,
    37  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
    38  		Steps: []resource.TestStep{
    39  			resource.TestStep{
    40  				Config: testAccComputeV2Instance_basic,
    41  				Check: resource.ComposeTestCheckFunc(
    42  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
    43  					testAccCheckComputeV2InstanceMetadata(&instance, "foo", "bar"),
    44  				),
    45  			},
    46  		},
    47  	})
    48  }
    49  
    50  func TestAccComputeV2Instance_volumeAttach(t *testing.T) {
    51  	var instance servers.Server
    52  	var volume volumes.Volume
    53  
    54  	var testAccComputeV2Instance_volumeAttach = fmt.Sprintf(`
    55  		resource "openstack_blockstorage_volume_v1" "myvol" {
    56  			name = "myvol"
    57  			size = 1
    58  		}
    59  
    60  		resource "openstack_compute_instance_v2" "foo" {
    61  			name = "terraform-test"
    62  			security_groups = ["default"]
    63  			volume {
    64  				volume_id = "${openstack_blockstorage_volume_v1.myvol.id}"
    65  			}
    66  		}`)
    67  
    68  	resource.Test(t, resource.TestCase{
    69  		PreCheck:     func() { testAccPreCheck(t) },
    70  		Providers:    testAccProviders,
    71  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
    72  		Steps: []resource.TestStep{
    73  			resource.TestStep{
    74  				Config: testAccComputeV2Instance_volumeAttach,
    75  				Check: resource.ComposeTestCheckFunc(
    76  					testAccCheckBlockStorageV1VolumeExists(t, "openstack_blockstorage_volume_v1.myvol", &volume),
    77  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
    78  					testAccCheckComputeV2InstanceVolumeAttachment(&instance, &volume),
    79  				),
    80  			},
    81  		},
    82  	})
    83  }
    84  
    85  func TestAccComputeV2Instance_volumeAttachPostCreation(t *testing.T) {
    86  	var instance servers.Server
    87  	var volume volumes.Volume
    88  
    89  	var testAccComputeV2Instance_volumeAttachPostCreationInstance = fmt.Sprintf(`
    90  		resource "openstack_compute_instance_v2" "foo" {
    91  			name = "terraform-test"
    92  			security_groups = ["default"]
    93  		}`)
    94  
    95  	var testAccComputeV2Instance_volumeAttachPostCreationInstanceAndVolume = fmt.Sprintf(`
    96  		resource "openstack_blockstorage_volume_v1" "myvol" {
    97  			name = "myvol"
    98  			size = 1
    99  		}
   100  
   101  		resource "openstack_compute_instance_v2" "foo" {
   102  			name = "terraform-test"
   103  			security_groups = ["default"]
   104  			volume {
   105  				volume_id = "${openstack_blockstorage_volume_v1.myvol.id}"
   106  			}
   107  		}`)
   108  
   109  	resource.Test(t, resource.TestCase{
   110  		PreCheck:     func() { testAccPreCheck(t) },
   111  		Providers:    testAccProviders,
   112  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   113  		Steps: []resource.TestStep{
   114  			resource.TestStep{
   115  				Config: testAccComputeV2Instance_volumeAttachPostCreationInstance,
   116  				Check: resource.ComposeTestCheckFunc(
   117  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   118  				),
   119  			},
   120  			resource.TestStep{
   121  				Config: testAccComputeV2Instance_volumeAttachPostCreationInstanceAndVolume,
   122  				Check: resource.ComposeTestCheckFunc(
   123  					testAccCheckBlockStorageV1VolumeExists(t, "openstack_blockstorage_volume_v1.myvol", &volume),
   124  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   125  					testAccCheckComputeV2InstanceVolumeAttachment(&instance, &volume),
   126  				),
   127  			},
   128  		},
   129  	})
   130  }
   131  
   132  func TestAccComputeV2Instance_volumeDetachPostCreation(t *testing.T) {
   133  	var instance servers.Server
   134  	var volume volumes.Volume
   135  
   136  	var testAccComputeV2Instance_volumeDetachPostCreationInstanceAndVolume = fmt.Sprintf(`
   137  		resource "openstack_blockstorage_volume_v1" "myvol" {
   138  			name = "myvol"
   139  			size = 1
   140  		}
   141  
   142  		resource "openstack_compute_instance_v2" "foo" {
   143  			name = "terraform-test"
   144  			security_groups = ["default"]
   145  			volume {
   146  				volume_id = "${openstack_blockstorage_volume_v1.myvol.id}"
   147  			}
   148  		}`)
   149  
   150  	var testAccComputeV2Instance_volumeDetachPostCreationInstance = fmt.Sprintf(`
   151  		resource "openstack_compute_instance_v2" "foo" {
   152  			name = "terraform-test"
   153  			security_groups = ["default"]
   154  		}`)
   155  
   156  	resource.Test(t, resource.TestCase{
   157  		PreCheck:     func() { testAccPreCheck(t) },
   158  		Providers:    testAccProviders,
   159  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   160  		Steps: []resource.TestStep{
   161  			resource.TestStep{
   162  				Config: testAccComputeV2Instance_volumeDetachPostCreationInstanceAndVolume,
   163  				Check: resource.ComposeTestCheckFunc(
   164  					testAccCheckBlockStorageV1VolumeExists(t, "openstack_blockstorage_volume_v1.myvol", &volume),
   165  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   166  					testAccCheckComputeV2InstanceVolumeAttachment(&instance, &volume),
   167  				),
   168  			},
   169  			resource.TestStep{
   170  				Config: testAccComputeV2Instance_volumeDetachPostCreationInstance,
   171  				Check: resource.ComposeTestCheckFunc(
   172  					testAccCheckBlockStorageV1VolumeDoesNotExist(t, "openstack_blockstorage_volume_v1.myvol", &volume),
   173  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   174  					testAccCheckComputeV2InstanceVolumesDetached(&instance),
   175  				),
   176  			},
   177  		},
   178  	})
   179  }
   180  
   181  func TestAccComputeV2Instance_floatingIPAttach(t *testing.T) {
   182  	var instance servers.Server
   183  	var fip floatingip.FloatingIP
   184  	var testAccComputeV2Instance_floatingIPAttach = fmt.Sprintf(`
   185  		resource "openstack_compute_floatingip_v2" "myip" {
   186  		}
   187  
   188  		resource "openstack_compute_instance_v2" "foo" {
   189  			name = "terraform-test"
   190  			security_groups = ["default"]
   191  			floating_ip = "${openstack_compute_floatingip_v2.myip.address}"
   192  
   193  			network {
   194  				uuid = "%s"
   195  			}
   196  		}`,
   197  		os.Getenv("OS_NETWORK_ID"))
   198  
   199  	resource.Test(t, resource.TestCase{
   200  		PreCheck:     func() { testAccPreCheck(t) },
   201  		Providers:    testAccProviders,
   202  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   203  		Steps: []resource.TestStep{
   204  			resource.TestStep{
   205  				Config: testAccComputeV2Instance_floatingIPAttach,
   206  				Check: resource.ComposeTestCheckFunc(
   207  					testAccCheckComputeV2FloatingIPExists(t, "openstack_compute_floatingip_v2.myip", &fip),
   208  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   209  					testAccCheckComputeV2InstanceFloatingIPAttach(&instance, &fip),
   210  				),
   211  			},
   212  		},
   213  	})
   214  }
   215  
   216  func TestAccComputeV2Instance_multi_secgroups(t *testing.T) {
   217  	var instance servers.Server
   218  	var secgroup secgroups.SecurityGroup
   219  	var testAccComputeV2Instance_multi_secgroups = fmt.Sprintf(`
   220  		resource "openstack_compute_secgroup_v2" "foo" {
   221  			name = "terraform-test"
   222  			description = "a security group"
   223  			rule {
   224  				from_port = 22
   225  				to_port = 22
   226  				ip_protocol = "tcp"
   227  				cidr = "0.0.0.0/0"
   228  			}
   229  		}
   230  
   231  		resource "openstack_compute_instance_v2" "foo" {
   232  			name = "terraform-test"
   233  			security_groups = ["default", "${openstack_compute_secgroup_v2.foo.name}"]
   234  			network {
   235  				uuid = "%s"
   236  			}
   237  		}`,
   238  		os.Getenv("OS_NETWORK_ID"))
   239  
   240  	resource.Test(t, resource.TestCase{
   241  		PreCheck:     func() { testAccPreCheck(t) },
   242  		Providers:    testAccProviders,
   243  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   244  		Steps: []resource.TestStep{
   245  			resource.TestStep{
   246  				Config: testAccComputeV2Instance_multi_secgroups,
   247  				Check: resource.ComposeTestCheckFunc(
   248  					testAccCheckComputeV2SecGroupExists(t, "openstack_compute_secgroup_v2.foo", &secgroup),
   249  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   250  				),
   251  			},
   252  		},
   253  	})
   254  }
   255  
   256  func TestAccComputeV2Instance_bootFromVolumeImage(t *testing.T) {
   257  	var instance servers.Server
   258  	var testAccComputeV2Instance_bootFromVolumeImage = fmt.Sprintf(`
   259  		resource "openstack_compute_instance_v2" "foo" {
   260  			name = "terraform-test"
   261  			security_groups = ["default"]
   262  			block_device {
   263  				uuid = "%s"
   264  				source_type = "image"
   265  				volume_size = 5
   266  				boot_index = 0
   267  				destination_type = "volume"
   268  				delete_on_termination = true
   269  			}
   270  		}`,
   271  		os.Getenv("OS_IMAGE_ID"))
   272  
   273  	resource.Test(t, resource.TestCase{
   274  		PreCheck:     func() { testAccPreCheck(t) },
   275  		Providers:    testAccProviders,
   276  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   277  		Steps: []resource.TestStep{
   278  			resource.TestStep{
   279  				Config: testAccComputeV2Instance_bootFromVolumeImage,
   280  				Check: resource.ComposeTestCheckFunc(
   281  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   282  					testAccCheckComputeV2InstanceBootVolumeAttachment(&instance),
   283  				),
   284  			},
   285  		},
   286  	})
   287  }
   288  
   289  func TestAccComputeV2Instance_bootFromVolumeVolume(t *testing.T) {
   290  	var instance servers.Server
   291  	var testAccComputeV2Instance_bootFromVolumeVolume = fmt.Sprintf(`
   292  	  resource "openstack_blockstorage_volume_v1" "foo" {
   293  			name = "terraform-test"
   294  			size = 5
   295  			image_id = "%s"
   296  		}
   297  
   298  		resource "openstack_compute_instance_v2" "foo" {
   299  			name = "terraform-test"
   300  			security_groups = ["default"]
   301  			block_device {
   302  				uuid = "${openstack_blockstorage_volume_v1.foo.id}"
   303  				source_type = "volume"
   304  				volume_size = 5
   305  				boot_index = 0
   306  				destination_type = "volume"
   307  				delete_on_termination = true
   308  			}
   309  		}`,
   310  		os.Getenv("OS_IMAGE_ID"))
   311  
   312  	resource.Test(t, resource.TestCase{
   313  		PreCheck:     func() { testAccPreCheck(t) },
   314  		Providers:    testAccProviders,
   315  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   316  		Steps: []resource.TestStep{
   317  			resource.TestStep{
   318  				Config: testAccComputeV2Instance_bootFromVolumeVolume,
   319  				Check: resource.ComposeTestCheckFunc(
   320  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   321  					testAccCheckComputeV2InstanceBootVolumeAttachment(&instance),
   322  				),
   323  			},
   324  		},
   325  	})
   326  }
   327  
   328  // TODO: verify the personality really exists on the instance.
   329  func TestAccComputeV2Instance_personality(t *testing.T) {
   330  	var instance servers.Server
   331  	var testAccComputeV2Instance_personality = fmt.Sprintf(`
   332  		resource "openstack_compute_instance_v2" "foo" {
   333  			name = "terraform-test"
   334  			security_groups = ["default"]
   335  			personality {
   336  				file = "/tmp/foobar.txt"
   337  				content = "happy"
   338  			}
   339  			personality {
   340  				file = "/tmp/barfoo.txt"
   341  				content = "angry"
   342  			}
   343  		}`)
   344  
   345  	resource.Test(t, resource.TestCase{
   346  		PreCheck:     func() { testAccPreCheck(t) },
   347  		Providers:    testAccProviders,
   348  		CheckDestroy: testAccCheckComputeV2InstanceDestroy,
   349  		Steps: []resource.TestStep{
   350  			resource.TestStep{
   351  				Config: testAccComputeV2Instance_personality,
   352  				Check: resource.ComposeTestCheckFunc(
   353  					testAccCheckComputeV2InstanceExists(t, "openstack_compute_instance_v2.foo", &instance),
   354  				),
   355  			},
   356  		},
   357  	})
   358  }
   359  
   360  func testAccCheckComputeV2InstanceDestroy(s *terraform.State) error {
   361  	config := testAccProvider.Meta().(*Config)
   362  	computeClient, err := config.computeV2Client(OS_REGION_NAME)
   363  	if err != nil {
   364  		return fmt.Errorf("(testAccCheckComputeV2InstanceDestroy) Error creating OpenStack compute client: %s", err)
   365  	}
   366  
   367  	for _, rs := range s.RootModule().Resources {
   368  		if rs.Type != "openstack_compute_instance_v2" {
   369  			continue
   370  		}
   371  
   372  		_, err := servers.Get(computeClient, rs.Primary.ID).Extract()
   373  		if err == nil {
   374  			return fmt.Errorf("Instance still exists")
   375  		}
   376  	}
   377  
   378  	return nil
   379  }
   380  
   381  func testAccCheckComputeV2InstanceExists(t *testing.T, n string, instance *servers.Server) resource.TestCheckFunc {
   382  	return func(s *terraform.State) error {
   383  		rs, ok := s.RootModule().Resources[n]
   384  		if !ok {
   385  			return fmt.Errorf("Not found: %s", n)
   386  		}
   387  
   388  		if rs.Primary.ID == "" {
   389  			return fmt.Errorf("No ID is set")
   390  		}
   391  
   392  		config := testAccProvider.Meta().(*Config)
   393  		computeClient, err := config.computeV2Client(OS_REGION_NAME)
   394  		if err != nil {
   395  			return fmt.Errorf("(testAccCheckComputeV2InstanceExists) Error creating OpenStack compute client: %s", err)
   396  		}
   397  
   398  		found, err := servers.Get(computeClient, rs.Primary.ID).Extract()
   399  		if err != nil {
   400  			return err
   401  		}
   402  
   403  		if found.ID != rs.Primary.ID {
   404  			return fmt.Errorf("Instance not found")
   405  		}
   406  
   407  		*instance = *found
   408  
   409  		return nil
   410  	}
   411  }
   412  
   413  func testAccCheckComputeV2InstanceMetadata(
   414  	instance *servers.Server, k string, v string) resource.TestCheckFunc {
   415  	return func(s *terraform.State) error {
   416  		if instance.Metadata == nil {
   417  			return fmt.Errorf("No metadata")
   418  		}
   419  
   420  		for key, value := range instance.Metadata {
   421  			if k != key {
   422  				continue
   423  			}
   424  
   425  			if v == value.(string) {
   426  				return nil
   427  			}
   428  
   429  			return fmt.Errorf("Bad value for %s: %s", k, value)
   430  		}
   431  
   432  		return fmt.Errorf("Metadata not found: %s", k)
   433  	}
   434  }
   435  
   436  func testAccCheckComputeV2InstanceVolumeAttachment(
   437  	instance *servers.Server, volume *volumes.Volume) resource.TestCheckFunc {
   438  	return func(s *terraform.State) error {
   439  		var attachments []volumeattach.VolumeAttachment
   440  
   441  		config := testAccProvider.Meta().(*Config)
   442  		computeClient, err := config.computeV2Client(OS_REGION_NAME)
   443  		if err != nil {
   444  			return err
   445  		}
   446  		err = volumeattach.List(computeClient, instance.ID).EachPage(func(page pagination.Page) (bool, error) {
   447  			actual, err := volumeattach.ExtractVolumeAttachments(page)
   448  			if err != nil {
   449  				return false, fmt.Errorf("Unable to lookup attachment: %s", err)
   450  			}
   451  
   452  			attachments = actual
   453  			return true, nil
   454  		})
   455  
   456  		for _, attachment := range attachments {
   457  			if attachment.VolumeID == volume.ID {
   458  				return nil
   459  			}
   460  		}
   461  
   462  		return fmt.Errorf("Volume not found: %s", volume.ID)
   463  	}
   464  }
   465  
   466  func testAccCheckComputeV2InstanceVolumesDetached(instance *servers.Server) resource.TestCheckFunc {
   467  	return func(s *terraform.State) error {
   468  		var attachments []volumeattach.VolumeAttachment
   469  
   470  		config := testAccProvider.Meta().(*Config)
   471  		computeClient, err := config.computeV2Client(OS_REGION_NAME)
   472  		if err != nil {
   473  			return err
   474  		}
   475  		err = volumeattach.List(computeClient, instance.ID).EachPage(func(page pagination.Page) (bool, error) {
   476  			actual, err := volumeattach.ExtractVolumeAttachments(page)
   477  			if err != nil {
   478  				return false, fmt.Errorf("Unable to lookup attachment: %s", err)
   479  			}
   480  
   481  			attachments = actual
   482  			return true, nil
   483  		})
   484  
   485  		if len(attachments) > 0 {
   486  			return fmt.Errorf("Volumes are still attached.")
   487  		}
   488  
   489  		return nil
   490  	}
   491  }
   492  
   493  func testAccCheckComputeV2InstanceBootVolumeAttachment(
   494  	instance *servers.Server) resource.TestCheckFunc {
   495  	return func(s *terraform.State) error {
   496  		var attachments []volumeattach.VolumeAttachment
   497  
   498  		config := testAccProvider.Meta().(*Config)
   499  		computeClient, err := config.computeV2Client(OS_REGION_NAME)
   500  		if err != nil {
   501  			return err
   502  		}
   503  		err = volumeattach.List(computeClient, instance.ID).EachPage(func(page pagination.Page) (bool, error) {
   504  			actual, err := volumeattach.ExtractVolumeAttachments(page)
   505  			if err != nil {
   506  				return false, fmt.Errorf("Unable to lookup attachment: %s", err)
   507  			}
   508  
   509  			attachments = actual
   510  			return true, nil
   511  		})
   512  
   513  		if len(attachments) == 1 {
   514  			return nil
   515  		}
   516  
   517  		return fmt.Errorf("No attached volume found.")
   518  	}
   519  }
   520  
   521  func testAccCheckComputeV2InstanceFloatingIPAttach(
   522  	instance *servers.Server, fip *floatingip.FloatingIP) resource.TestCheckFunc {
   523  	return func(s *terraform.State) error {
   524  		if fip.InstanceID == instance.ID {
   525  			return nil
   526  		}
   527  
   528  		return fmt.Errorf("Floating IP %s was not attached to instance %s", fip.ID, instance.ID)
   529  
   530  	}
   531  }