github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/digitalocean/resource_digitalocean_droplet_test.go (about)

     1  package digitalocean
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/digitalocean/godo"
    10  	"github.com/hashicorp/terraform/helper/resource"
    11  	"github.com/hashicorp/terraform/terraform"
    12  )
    13  
    14  func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
    15  	var droplet godo.Droplet
    16  
    17  	resource.Test(t, resource.TestCase{
    18  		PreCheck:     func() { testAccPreCheck(t) },
    19  		Providers:    testAccProviders,
    20  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
    21  		Steps: []resource.TestStep{
    22  			resource.TestStep{
    23  				Config: testAccCheckDigitalOceanDropletConfig_basic,
    24  				Check: resource.ComposeTestCheckFunc(
    25  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
    26  					testAccCheckDigitalOceanDropletAttributes(&droplet),
    27  					resource.TestCheckResourceAttr(
    28  						"digitalocean_droplet.foobar", "name", "foo"),
    29  					resource.TestCheckResourceAttr(
    30  						"digitalocean_droplet.foobar", "size", "512mb"),
    31  					resource.TestCheckResourceAttr(
    32  						"digitalocean_droplet.foobar", "image", "centos-7-x64"),
    33  					resource.TestCheckResourceAttr(
    34  						"digitalocean_droplet.foobar", "region", "nyc3"),
    35  					resource.TestCheckResourceAttr(
    36  						"digitalocean_droplet.foobar", "user_data", "foobar"),
    37  				),
    38  			},
    39  		},
    40  	})
    41  }
    42  
    43  func TestAccDigitalOceanDroplet_Update(t *testing.T) {
    44  	var droplet godo.Droplet
    45  
    46  	resource.Test(t, resource.TestCase{
    47  		PreCheck:     func() { testAccPreCheck(t) },
    48  		Providers:    testAccProviders,
    49  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
    50  		Steps: []resource.TestStep{
    51  			resource.TestStep{
    52  				Config: testAccCheckDigitalOceanDropletConfig_basic,
    53  				Check: resource.ComposeTestCheckFunc(
    54  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
    55  					testAccCheckDigitalOceanDropletAttributes(&droplet),
    56  				),
    57  			},
    58  
    59  			resource.TestStep{
    60  				Config: testAccCheckDigitalOceanDropletConfig_RenameAndResize,
    61  				Check: resource.ComposeTestCheckFunc(
    62  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
    63  					testAccCheckDigitalOceanDropletRenamedAndResized(&droplet),
    64  					resource.TestCheckResourceAttr(
    65  						"digitalocean_droplet.foobar", "name", "baz"),
    66  					resource.TestCheckResourceAttr(
    67  						"digitalocean_droplet.foobar", "size", "1gb"),
    68  					resource.TestCheckResourceAttr(
    69  						"digitalocean_droplet.foobar", "disk", "30"),
    70  				),
    71  			},
    72  		},
    73  	})
    74  }
    75  
    76  func TestAccDigitalOceanDroplet_ResizeWithOutDisk(t *testing.T) {
    77  	var droplet godo.Droplet
    78  
    79  	resource.Test(t, resource.TestCase{
    80  		PreCheck:     func() { testAccPreCheck(t) },
    81  		Providers:    testAccProviders,
    82  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
    83  		Steps: []resource.TestStep{
    84  			resource.TestStep{
    85  				Config: testAccCheckDigitalOceanDropletConfig_basic,
    86  				Check: resource.ComposeTestCheckFunc(
    87  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
    88  					testAccCheckDigitalOceanDropletAttributes(&droplet),
    89  				),
    90  			},
    91  
    92  			resource.TestStep{
    93  				Config: testAccCheckDigitalOceanDropletConfig_resize_without_disk,
    94  				Check: resource.ComposeTestCheckFunc(
    95  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
    96  					testAccCheckDigitalOceanDropletResizeWithOutDisk(&droplet),
    97  					resource.TestCheckResourceAttr(
    98  						"digitalocean_droplet.foobar", "size", "1gb"),
    99  					resource.TestCheckResourceAttr(
   100  						"digitalocean_droplet.foobar", "disk", "20"),
   101  				),
   102  			},
   103  		},
   104  	})
   105  }
   106  
   107  func TestAccDigitalOceanDroplet_UpdateUserData(t *testing.T) {
   108  	var afterCreate, afterUpdate godo.Droplet
   109  
   110  	resource.Test(t, resource.TestCase{
   111  		PreCheck:     func() { testAccPreCheck(t) },
   112  		Providers:    testAccProviders,
   113  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
   114  		Steps: []resource.TestStep{
   115  			resource.TestStep{
   116  				Config: testAccCheckDigitalOceanDropletConfig_basic,
   117  				Check: resource.ComposeTestCheckFunc(
   118  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate),
   119  					testAccCheckDigitalOceanDropletAttributes(&afterCreate),
   120  				),
   121  			},
   122  
   123  			resource.TestStep{
   124  				Config: testAccCheckDigitalOceanDropletConfig_userdata_update,
   125  				Check: resource.ComposeTestCheckFunc(
   126  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate),
   127  					resource.TestCheckResourceAttr(
   128  						"digitalocean_droplet.foobar",
   129  						"user_data",
   130  						"foobar foobar"),
   131  					testAccCheckDigitalOceanDropletRecreated(
   132  						t, &afterCreate, &afterUpdate),
   133  				),
   134  			},
   135  		},
   136  	})
   137  }
   138  
   139  func TestAccDigitalOceanDroplet_UpdateTags(t *testing.T) {
   140  	var afterCreate, afterUpdate godo.Droplet
   141  
   142  	resource.Test(t, resource.TestCase{
   143  		PreCheck:     func() { testAccPreCheck(t) },
   144  		Providers:    testAccProviders,
   145  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
   146  		Steps: []resource.TestStep{
   147  			resource.TestStep{
   148  				Config: testAccCheckDigitalOceanDropletConfig_basic,
   149  				Check: resource.ComposeTestCheckFunc(
   150  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterCreate),
   151  					testAccCheckDigitalOceanDropletAttributes(&afterCreate),
   152  				),
   153  			},
   154  
   155  			resource.TestStep{
   156  				Config: testAccCheckDigitalOceanDropletConfig_tag_update,
   157  				Check: resource.ComposeTestCheckFunc(
   158  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &afterUpdate),
   159  					resource.TestCheckResourceAttr(
   160  						"digitalocean_droplet.foobar",
   161  						"tags.#",
   162  						"1"),
   163  					resource.TestCheckResourceAttr(
   164  						"digitalocean_droplet.foobar",
   165  						"tags.0",
   166  						"barbaz"),
   167  				),
   168  			},
   169  		},
   170  	})
   171  }
   172  
   173  func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) {
   174  	var droplet godo.Droplet
   175  
   176  	resource.Test(t, resource.TestCase{
   177  		PreCheck:     func() { testAccPreCheck(t) },
   178  		Providers:    testAccProviders,
   179  		CheckDestroy: testAccCheckDigitalOceanDropletDestroy,
   180  		Steps: []resource.TestStep{
   181  			resource.TestStep{
   182  				Config: testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6,
   183  				Check: resource.ComposeTestCheckFunc(
   184  					testAccCheckDigitalOceanDropletExists("digitalocean_droplet.foobar", &droplet),
   185  					testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(&droplet),
   186  					resource.TestCheckResourceAttr(
   187  						"digitalocean_droplet.foobar", "private_networking", "true"),
   188  					resource.TestCheckResourceAttr(
   189  						"digitalocean_droplet.foobar", "ipv6", "true"),
   190  				),
   191  			},
   192  		},
   193  	})
   194  }
   195  
   196  func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
   197  	client := testAccProvider.Meta().(*godo.Client)
   198  
   199  	for _, rs := range s.RootModule().Resources {
   200  		if rs.Type != "digitalocean_droplet" {
   201  			continue
   202  		}
   203  
   204  		id, err := strconv.Atoi(rs.Primary.ID)
   205  		if err != nil {
   206  			return err
   207  		}
   208  
   209  		// Try to find the Droplet
   210  		_, _, err = client.Droplets.Get(id)
   211  
   212  		// Wait
   213  
   214  		if err != nil && !strings.Contains(err.Error(), "404") {
   215  			return fmt.Errorf(
   216  				"Error waiting for droplet (%s) to be destroyed: %s",
   217  				rs.Primary.ID, err)
   218  		}
   219  	}
   220  
   221  	return nil
   222  }
   223  
   224  func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.TestCheckFunc {
   225  	return func(s *terraform.State) error {
   226  
   227  		if droplet.Image.Slug != "centos-7-x64" {
   228  			return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
   229  		}
   230  
   231  		if droplet.Size.Slug != "512mb" {
   232  			return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug)
   233  		}
   234  
   235  		if droplet.Region.Slug != "nyc3" {
   236  			return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug)
   237  		}
   238  
   239  		if droplet.Name != "foo" {
   240  			return fmt.Errorf("Bad name: %s", droplet.Name)
   241  		}
   242  		return nil
   243  	}
   244  }
   245  
   246  func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *godo.Droplet) resource.TestCheckFunc {
   247  	return func(s *terraform.State) error {
   248  
   249  		if droplet.Size.Slug != "1gb" {
   250  			return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
   251  		}
   252  
   253  		if droplet.Name != "baz" {
   254  			return fmt.Errorf("Bad name: %s", droplet.Name)
   255  		}
   256  
   257  		if droplet.Disk != 30 {
   258  			return fmt.Errorf("Bad disk: %s", droplet.Disk)
   259  		}
   260  
   261  		return nil
   262  	}
   263  }
   264  
   265  func testAccCheckDigitalOceanDropletResizeWithOutDisk(droplet *godo.Droplet) resource.TestCheckFunc {
   266  	return func(s *terraform.State) error {
   267  
   268  		if droplet.Size.Slug != "1gb" {
   269  			return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
   270  		}
   271  
   272  		if droplet.Disk != 20 {
   273  			return fmt.Errorf("Bad disk: %s", droplet.Disk)
   274  		}
   275  
   276  		return nil
   277  	}
   278  }
   279  
   280  func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc {
   281  	return func(s *terraform.State) error {
   282  
   283  		if droplet.Image.Slug != "centos-7-x64" {
   284  			return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
   285  		}
   286  
   287  		if droplet.Size.Slug != "1gb" {
   288  			return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug)
   289  		}
   290  
   291  		if droplet.Region.Slug != "sgp1" {
   292  			return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug)
   293  		}
   294  
   295  		if droplet.Name != "baz" {
   296  			return fmt.Errorf("Bad name: %s", droplet.Name)
   297  		}
   298  
   299  		if findIPv4AddrByType(droplet, "private") == "" {
   300  			return fmt.Errorf("No ipv4 private: %s", findIPv4AddrByType(droplet, "private"))
   301  		}
   302  
   303  		// if droplet.IPV6Address("private") == "" {
   304  		// 	return fmt.Errorf("No ipv6 private: %s", droplet.IPV6Address("private"))
   305  		// }
   306  
   307  		if findIPv4AddrByType(droplet, "public") == "" {
   308  			return fmt.Errorf("No ipv4 public: %s", findIPv4AddrByType(droplet, "public"))
   309  		}
   310  
   311  		if findIPv6AddrByType(droplet, "public") == "" {
   312  			return fmt.Errorf("No ipv6 public: %s", findIPv6AddrByType(droplet, "public"))
   313  		}
   314  
   315  		for _, rs := range s.RootModule().Resources {
   316  			if rs.Type != "digitalocean_droplet" {
   317  				continue
   318  			}
   319  			if rs.Primary.Attributes["ipv6_address"] != strings.ToLower(findIPv6AddrByType(droplet, "public")) {
   320  				return fmt.Errorf("IPV6 Address should be lowercase")
   321  			}
   322  
   323  		}
   324  
   325  		return nil
   326  	}
   327  }
   328  
   329  func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc {
   330  	return func(s *terraform.State) error {
   331  		rs, ok := s.RootModule().Resources[n]
   332  		if !ok {
   333  			return fmt.Errorf("Not found: %s", n)
   334  		}
   335  
   336  		if rs.Primary.ID == "" {
   337  			return fmt.Errorf("No Droplet ID is set")
   338  		}
   339  
   340  		client := testAccProvider.Meta().(*godo.Client)
   341  
   342  		id, err := strconv.Atoi(rs.Primary.ID)
   343  		if err != nil {
   344  			return err
   345  		}
   346  
   347  		// Try to find the Droplet
   348  		retrieveDroplet, _, err := client.Droplets.Get(id)
   349  
   350  		if err != nil {
   351  			return err
   352  		}
   353  
   354  		if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID {
   355  			return fmt.Errorf("Droplet not found")
   356  		}
   357  
   358  		*droplet = *retrieveDroplet
   359  
   360  		return nil
   361  	}
   362  }
   363  
   364  func testAccCheckDigitalOceanDropletRecreated(t *testing.T,
   365  	before, after *godo.Droplet) resource.TestCheckFunc {
   366  	return func(s *terraform.State) error {
   367  		if before.ID == after.ID {
   368  			t.Fatalf("Expected change of droplet IDs, but both were %v", before.ID)
   369  		}
   370  		return nil
   371  	}
   372  }
   373  
   374  // Not sure if this check should remain here as the underlaying
   375  // function is changed and is tested indirectly by almost all
   376  // other test already
   377  //
   378  //func Test_new_droplet_state_refresh_func(t *testing.T) {
   379  //	droplet := godo.Droplet{
   380  //		Name: "foobar",
   381  //	}
   382  //	resourceMap, _ := resource_digitalocean_droplet_update_state(
   383  //		&terraform.InstanceState{Attributes: map[string]string{}}, &droplet)
   384  //
   385  //	// See if we can access our attribute
   386  //	if _, ok := resourceMap.Attributes["name"]; !ok {
   387  //		t.Fatalf("bad name: %s", resourceMap.Attributes)
   388  //	}
   389  //
   390  //}
   391  
   392  var testAccCheckDigitalOceanDropletConfig_basic = fmt.Sprintf(`
   393  resource "digitalocean_ssh_key" "foobar" {
   394    name       = "foobar"
   395    public_key = "%s"
   396  }
   397  
   398  resource "digitalocean_droplet" "foobar" {
   399    name      = "foo"
   400    size      = "512mb"
   401    image     = "centos-7-x64"
   402    region    = "nyc3"
   403    user_data = "foobar"
   404    ssh_keys  = ["${digitalocean_ssh_key.foobar.id}"]
   405  }
   406  `, testAccValidPublicKey)
   407  
   408  var testAccCheckDigitalOceanDropletConfig_tag_update = fmt.Sprintf(`
   409  resource "digitalocean_tag" "barbaz" {
   410    name       = "barbaz"
   411  }
   412  
   413  resource "digitalocean_ssh_key" "foobar" {
   414    name       = "foobar"
   415    public_key = "%s"
   416  }
   417  
   418  resource "digitalocean_droplet" "foobar" {
   419    name      = "foo"
   420    size      = "512mb"
   421    image     = "centos-7-x64"
   422    region    = "nyc3"
   423    user_data = "foobar"
   424    ssh_keys  = ["${digitalocean_ssh_key.foobar.id}"]
   425    tags  = ["${digitalocean_tag.barbaz.id}"]
   426  }
   427  `, testAccValidPublicKey)
   428  
   429  var testAccCheckDigitalOceanDropletConfig_userdata_update = fmt.Sprintf(`
   430  resource "digitalocean_ssh_key" "foobar" {
   431    name       = "foobar"
   432    public_key = "%s"
   433  }
   434  
   435  resource "digitalocean_droplet" "foobar" {
   436    name      = "foo"
   437    size      = "512mb"
   438    image     = "centos-7-x64"
   439    region    = "nyc3"
   440    user_data = "foobar foobar"
   441    ssh_keys  = ["${digitalocean_ssh_key.foobar.id}"]
   442  }
   443  `, testAccValidPublicKey)
   444  
   445  var testAccCheckDigitalOceanDropletConfig_RenameAndResize = fmt.Sprintf(`
   446  resource "digitalocean_ssh_key" "foobar" {
   447    name       = "foobar"
   448    public_key = "%s"
   449  }
   450  
   451  resource "digitalocean_droplet" "foobar" {
   452    name     = "baz"
   453    size     = "1gb"
   454    image    = "centos-7-x64"
   455    region   = "nyc3"
   456    ssh_keys = ["${digitalocean_ssh_key.foobar.id}"]
   457  }
   458  `, testAccValidPublicKey)
   459  
   460  var testAccCheckDigitalOceanDropletConfig_resize_without_disk = fmt.Sprintf(`
   461  resource "digitalocean_ssh_key" "foobar" {
   462    name       = "foobar"
   463    public_key = "%s"
   464  }
   465  
   466  resource "digitalocean_droplet" "foobar" {
   467    name     = "foo"
   468    size     = "1gb"
   469    image    = "centos-7-x64"
   470    region   = "nyc3"
   471    ssh_keys = ["${digitalocean_ssh_key.foobar.id}"]
   472    resize_disk = false
   473  }
   474  `, testAccValidPublicKey)
   475  
   476  // IPV6 only in singapore
   477  var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(`
   478  resource "digitalocean_ssh_key" "foobar" {
   479    name       = "foobar"
   480    public_key = "%s"
   481  }
   482  
   483  resource "digitalocean_droplet" "foobar" {
   484    name               = "baz"
   485    size               = "1gb"
   486    image              = "centos-7-x64"
   487    region             = "sgp1"
   488    ipv6               = true
   489    private_networking = true
   490    ssh_keys           = ["${digitalocean_ssh_key.foobar.id}"]
   491  }
   492  `, testAccValidPublicKey)