github.com/recobe182/terraform@v0.8.5-0.20170117231232-49ab22a935b7/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: %d", 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: %d", 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 var testAccCheckDigitalOceanDropletConfig_basic = fmt.Sprintf(` 375 resource "digitalocean_ssh_key" "foobar" { 376 name = "foobar" 377 public_key = "%s" 378 } 379 380 resource "digitalocean_droplet" "foobar" { 381 name = "foo" 382 size = "512mb" 383 image = "centos-7-x64" 384 region = "nyc3" 385 user_data = "foobar" 386 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 387 } 388 `, testAccValidPublicKey) 389 390 var testAccCheckDigitalOceanDropletConfig_tag_update = fmt.Sprintf(` 391 resource "digitalocean_tag" "barbaz" { 392 name = "barbaz" 393 } 394 395 resource "digitalocean_ssh_key" "foobar" { 396 name = "foobar" 397 public_key = "%s" 398 } 399 400 resource "digitalocean_droplet" "foobar" { 401 name = "foo" 402 size = "512mb" 403 image = "centos-7-x64" 404 region = "nyc3" 405 user_data = "foobar" 406 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 407 tags = ["${digitalocean_tag.barbaz.id}"] 408 } 409 `, testAccValidPublicKey) 410 411 var testAccCheckDigitalOceanDropletConfig_userdata_update = fmt.Sprintf(` 412 resource "digitalocean_ssh_key" "foobar" { 413 name = "foobar" 414 public_key = "%s" 415 } 416 417 resource "digitalocean_droplet" "foobar" { 418 name = "foo" 419 size = "512mb" 420 image = "centos-7-x64" 421 region = "nyc3" 422 user_data = "foobar foobar" 423 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 424 } 425 `, testAccValidPublicKey) 426 427 var testAccCheckDigitalOceanDropletConfig_RenameAndResize = fmt.Sprintf(` 428 resource "digitalocean_ssh_key" "foobar" { 429 name = "foobar" 430 public_key = "%s" 431 } 432 433 resource "digitalocean_droplet" "foobar" { 434 name = "baz" 435 size = "1gb" 436 image = "centos-7-x64" 437 region = "nyc3" 438 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 439 } 440 `, testAccValidPublicKey) 441 442 var testAccCheckDigitalOceanDropletConfig_resize_without_disk = fmt.Sprintf(` 443 resource "digitalocean_ssh_key" "foobar" { 444 name = "foobar" 445 public_key = "%s" 446 } 447 448 resource "digitalocean_droplet" "foobar" { 449 name = "foo" 450 size = "1gb" 451 image = "centos-7-x64" 452 region = "nyc3" 453 user_data = "foobar" 454 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 455 resize_disk = false 456 } 457 `, testAccValidPublicKey) 458 459 // IPV6 only in singapore 460 var testAccCheckDigitalOceanDropletConfig_PrivateNetworkingIpv6 = fmt.Sprintf(` 461 resource "digitalocean_ssh_key" "foobar" { 462 name = "foobar" 463 public_key = "%s" 464 } 465 466 resource "digitalocean_droplet" "foobar" { 467 name = "baz" 468 size = "1gb" 469 image = "centos-7-x64" 470 region = "sgp1" 471 ipv6 = true 472 private_networking = true 473 ssh_keys = ["${digitalocean_ssh_key.foobar.id}"] 474 } 475 `, testAccValidPublicKey)