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