Merge pull request #1089 from rasa/use-slugs-for-digitalocean
builder/digitalocean: use names/slugs as well as IDs for image/region/si...
This commit is contained in:
commit
6f6d656267
|
@ -13,6 +13,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -22,6 +23,7 @@ const DIGITALOCEAN_API_URL = "https://api.digitalocean.com"
|
||||||
type Image struct {
|
type Image struct {
|
||||||
Id uint
|
Id uint
|
||||||
Name string
|
Name string
|
||||||
|
Slug string
|
||||||
Distribution string
|
Distribution string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +34,23 @@ type ImagesResp struct {
|
||||||
type Region struct {
|
type Region struct {
|
||||||
Id uint
|
Id uint
|
||||||
Name string
|
Name string
|
||||||
|
Slug string
|
||||||
}
|
}
|
||||||
|
|
||||||
type RegionsResp struct {
|
type RegionsResp struct {
|
||||||
Regions []Region
|
Regions []Region
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Size struct {
|
||||||
|
Id uint
|
||||||
|
Name string
|
||||||
|
Slug string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SizesResp struct {
|
||||||
|
Sizes []Size
|
||||||
|
}
|
||||||
|
|
||||||
type DigitalOceanClient struct {
|
type DigitalOceanClient struct {
|
||||||
// The http client for communicating
|
// The http client for communicating
|
||||||
client *http.Client
|
client *http.Client
|
||||||
|
@ -90,12 +103,28 @@ func (d DigitalOceanClient) DestroyKey(id uint) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a droplet and returns it's id
|
// Creates a droplet and returns it's id
|
||||||
func (d DigitalOceanClient) CreateDroplet(name string, size uint, image uint, region uint, keyId uint, privateNetworking bool) (uint, error) {
|
func (d DigitalOceanClient) CreateDroplet(name string, size string, image string, region string, keyId uint, privateNetworking bool) (uint, error) {
|
||||||
params := url.Values{}
|
params := url.Values{}
|
||||||
params.Set("name", name)
|
params.Set("name", name)
|
||||||
params.Set("size_id", fmt.Sprintf("%v", size))
|
|
||||||
params.Set("image_id", fmt.Sprintf("%v", image))
|
found_size, err := d.Size(size)
|
||||||
params.Set("region_id", fmt.Sprintf("%v", region))
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("Invalid size or lookup failure: '%s': %s", size, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
found_image, err := d.Image(image)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("Invalid image or lookup failure: '%s': %s", image, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
found_region, err := d.Region(region)
|
||||||
|
if err != nil {
|
||||||
|
return 0, fmt.Errorf("Invalid region or lookup failure: '%s': %s", region, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
params.Set("size_slug", found_size.Slug)
|
||||||
|
params.Set("image_slug", found_image.Slug)
|
||||||
|
params.Set("region_slug", found_region.Slug)
|
||||||
params.Set("ssh_key_ids", fmt.Sprintf("%v", keyId))
|
params.Set("ssh_key_ids", fmt.Sprintf("%v", keyId))
|
||||||
params.Set("private_networking", fmt.Sprintf("%v", privateNetworking))
|
params.Set("private_networking", fmt.Sprintf("%v", privateNetworking))
|
||||||
|
|
||||||
|
@ -263,6 +292,38 @@ func NewRequest(d DigitalOceanClient, path string, params url.Values) (map[strin
|
||||||
return nil, lastErr
|
return nil, lastErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d DigitalOceanClient) Image(slug_or_name_or_id string) (Image, error) {
|
||||||
|
images, err := d.Images()
|
||||||
|
if err != nil {
|
||||||
|
return Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, image := range images {
|
||||||
|
if strings.EqualFold(image.Slug, slug_or_name_or_id) {
|
||||||
|
return image, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, image := range images {
|
||||||
|
if strings.EqualFold(image.Name, slug_or_name_or_id) {
|
||||||
|
return image, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, image := range images {
|
||||||
|
id, err := strconv.Atoi(slug_or_name_or_id)
|
||||||
|
if err == nil {
|
||||||
|
if image.Id == uint(id) {
|
||||||
|
return image, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = errors.New(fmt.Sprintf("Unknown image '%v'", slug_or_name_or_id))
|
||||||
|
|
||||||
|
return Image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
// Returns all available regions.
|
// Returns all available regions.
|
||||||
func (d DigitalOceanClient) Regions() ([]Region, error) {
|
func (d DigitalOceanClient) Regions() ([]Region, error) {
|
||||||
resp, err := NewRequest(d, "regions", url.Values{})
|
resp, err := NewRequest(d, "regions", url.Values{})
|
||||||
|
@ -278,19 +339,81 @@ func (d DigitalOceanClient) Regions() ([]Region, error) {
|
||||||
return result.Regions, nil
|
return result.Regions, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d DigitalOceanClient) RegionName(region_id uint) (string, error) {
|
func (d DigitalOceanClient) Region(slug_or_name_or_id string) (Region, error) {
|
||||||
regions, err := d.Regions()
|
regions, err := d.Regions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return Region{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, region := range regions {
|
for _, region := range regions {
|
||||||
if region.Id == region_id {
|
if strings.EqualFold(region.Slug, slug_or_name_or_id) {
|
||||||
return region.Name, nil
|
return region, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = errors.New(fmt.Sprintf("Unknown region id %v", region_id))
|
for _, region := range regions {
|
||||||
|
if strings.EqualFold(region.Name, slug_or_name_or_id) {
|
||||||
return "", err
|
return region, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, region := range regions {
|
||||||
|
id, err := strconv.Atoi(slug_or_name_or_id)
|
||||||
|
if err == nil {
|
||||||
|
if region.Id == uint(id) {
|
||||||
|
return region, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = errors.New(fmt.Sprintf("Unknown region '%v'", slug_or_name_or_id))
|
||||||
|
|
||||||
|
return Region{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns all available sizes.
|
||||||
|
func (d DigitalOceanClient) Sizes() ([]Size, error) {
|
||||||
|
resp, err := NewRequest(d, "sizes", url.Values{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result SizesResp
|
||||||
|
if err := mapstructure.Decode(resp, &result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Sizes, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d DigitalOceanClient) Size(slug_or_name_or_id string) (Size, error) {
|
||||||
|
sizes, err := d.Sizes()
|
||||||
|
if err != nil {
|
||||||
|
return Size{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, size := range sizes {
|
||||||
|
if strings.EqualFold(size.Slug, slug_or_name_or_id) {
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, size := range sizes {
|
||||||
|
if strings.EqualFold(size.Name, slug_or_name_or_id) {
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, size := range sizes {
|
||||||
|
id, err := strconv.Atoi(slug_or_name_or_id)
|
||||||
|
if err == nil {
|
||||||
|
if size.Id == uint(id) {
|
||||||
|
return size, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = errors.New(fmt.Sprintf("Unknown size '%v'", slug_or_name_or_id))
|
||||||
|
|
||||||
|
return Size{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,6 @@ type Artifact struct {
|
||||||
// The name of the region
|
// The name of the region
|
||||||
regionName string
|
regionName string
|
||||||
|
|
||||||
// The ID of the region
|
|
||||||
regionId uint
|
|
||||||
|
|
||||||
// The client for making API calls
|
// The client for making API calls
|
||||||
client *DigitalOceanClient
|
client *DigitalOceanClient
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ func TestArtifact_Impl(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArtifactString(t *testing.T) {
|
func TestArtifactString(t *testing.T) {
|
||||||
a := &Artifact{"packer-foobar", 42, "San Francisco", 3, nil}
|
a := &Artifact{"packer-foobar", 42, "San Francisco", nil}
|
||||||
expected := "A snapshot was created: 'packer-foobar' in region 'San Francisco'"
|
expected := "A snapshot was created: 'packer-foobar' in region 'San Francisco'"
|
||||||
|
|
||||||
if a.String() != expected {
|
if a.String() != expected {
|
||||||
|
|
|
@ -15,6 +15,18 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// see https://api.digitalocean.com/images/?client_id=[client_id]&api_key=[api_key]
|
||||||
|
// name="Ubuntu 12.04.4 x64", id=3101045,
|
||||||
|
const DefaultImage = "ubuntu-12-04-x64"
|
||||||
|
|
||||||
|
// see https://api.digitalocean.com/regions/?client_id=[client_id]&api_key=[api_key]
|
||||||
|
// name="New York", id=1
|
||||||
|
const DefaultRegion = "nyc1"
|
||||||
|
|
||||||
|
// see https://api.digitalocean.com/sizes/?client_id=[client_id]&api_key=[api_key]
|
||||||
|
// name="512MB", id=66 (the smallest droplet size)
|
||||||
|
const DefaultSize = "512mb"
|
||||||
|
|
||||||
// The unique id for the builder
|
// The unique id for the builder
|
||||||
const BuilderId = "pearkes.digitalocean"
|
const BuilderId = "pearkes.digitalocean"
|
||||||
|
|
||||||
|
@ -30,6 +42,10 @@ type config struct {
|
||||||
SizeID uint `mapstructure:"size_id"`
|
SizeID uint `mapstructure:"size_id"`
|
||||||
ImageID uint `mapstructure:"image_id"`
|
ImageID uint `mapstructure:"image_id"`
|
||||||
|
|
||||||
|
Region string `mapstructure:"region"`
|
||||||
|
Size string `mapstructure:"size"`
|
||||||
|
Image string `mapstructure:"image"`
|
||||||
|
|
||||||
PrivateNetworking bool `mapstructure:"private_networking"`
|
PrivateNetworking bool `mapstructure:"private_networking"`
|
||||||
SnapshotName string `mapstructure:"snapshot_name"`
|
SnapshotName string `mapstructure:"snapshot_name"`
|
||||||
DropletName string `mapstructure:"droplet_name"`
|
DropletName string `mapstructure:"droplet_name"`
|
||||||
|
@ -78,19 +94,28 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) {
|
||||||
b.config.ClientID = os.Getenv("DIGITALOCEAN_CLIENT_ID")
|
b.config.ClientID = os.Getenv("DIGITALOCEAN_CLIENT_ID")
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.RegionID == 0 {
|
if b.config.Region == "" {
|
||||||
// Default to Region "New York"
|
if b.config.RegionID != 0 {
|
||||||
b.config.RegionID = 1
|
b.config.Region = fmt.Sprintf("%v", b.config.RegionID)
|
||||||
|
} else {
|
||||||
|
b.config.Region = DefaultRegion
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SizeID == 0 {
|
if b.config.Size == "" {
|
||||||
// Default to 512mb, the smallest droplet size
|
if b.config.SizeID != 0 {
|
||||||
b.config.SizeID = 66
|
b.config.Size = fmt.Sprintf("%v", b.config.SizeID)
|
||||||
|
} else {
|
||||||
|
b.config.Size = DefaultSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.ImageID == 0 {
|
if b.config.Image == "" {
|
||||||
// Default to base image "Ubuntu 12.04.4 x64 (id: 3101045)"
|
if b.config.ImageID != 0 {
|
||||||
b.config.ImageID = 3101045
|
b.config.Image = fmt.Sprintf("%v", b.config.ImageID)
|
||||||
|
} else {
|
||||||
|
b.config.Image = DefaultImage
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SnapshotName == "" {
|
if b.config.SnapshotName == "" {
|
||||||
|
@ -226,9 +251,18 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
region_id := state.Get("region_id").(uint)
|
sregion := state.Get("region")
|
||||||
|
|
||||||
|
var region string
|
||||||
|
|
||||||
|
if sregion != nil {
|
||||||
|
region = sregion.(string)
|
||||||
|
} else {
|
||||||
|
region = fmt.Sprintf("%v", state.Get("region_id").(uint))
|
||||||
|
}
|
||||||
|
|
||||||
|
found_region, err := client.Region(region)
|
||||||
|
|
||||||
regionName, err := client.RegionName(region_id)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -236,8 +270,7 @@ func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packe
|
||||||
artifact := &Artifact{
|
artifact := &Artifact{
|
||||||
snapshotName: state.Get("snapshot_name").(string),
|
snapshotName: state.Get("snapshot_name").(string),
|
||||||
snapshotId: state.Get("snapshot_image_id").(uint),
|
snapshotId: state.Get("snapshot_image_id").(uint),
|
||||||
regionId: region_id,
|
regionName: found_region.Name,
|
||||||
regionName: regionName,
|
|
||||||
client: client,
|
client: client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@ func TestBuilderPrepare_InvalidKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_RegionID(t *testing.T) {
|
func TestBuilderPrepare_Region(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
||||||
|
@ -155,12 +155,15 @@ func TestBuilderPrepare_RegionID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.RegionID != 1 {
|
if b.config.Region != DefaultRegion {
|
||||||
t.Errorf("invalid: %d", b.config.RegionID)
|
t.Errorf("found %s, expected %s", b.config.Region, DefaultRegion)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected := "sfo1"
|
||||||
|
|
||||||
// Test set
|
// Test set
|
||||||
config["region_id"] = 2
|
config["region_id"] = 0
|
||||||
|
config["region"] = expected
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
warnings, err = b.Prepare(config)
|
warnings, err = b.Prepare(config)
|
||||||
if len(warnings) > 0 {
|
if len(warnings) > 0 {
|
||||||
|
@ -170,12 +173,12 @@ func TestBuilderPrepare_RegionID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.RegionID != 2 {
|
if b.config.Region != expected {
|
||||||
t.Errorf("invalid: %d", b.config.RegionID)
|
t.Errorf("found %s, expected %s", b.config.Region, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_SizeID(t *testing.T) {
|
func TestBuilderPrepare_Size(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
||||||
|
@ -188,12 +191,15 @@ func TestBuilderPrepare_SizeID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SizeID != 66 {
|
if b.config.Size != DefaultSize {
|
||||||
t.Errorf("invalid: %d", b.config.SizeID)
|
t.Errorf("found %s, expected %s", b.config.Size, DefaultSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected := "1024mb"
|
||||||
|
|
||||||
// Test set
|
// Test set
|
||||||
config["size_id"] = 67
|
config["size_id"] = 0
|
||||||
|
config["size"] = expected
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
warnings, err = b.Prepare(config)
|
warnings, err = b.Prepare(config)
|
||||||
if len(warnings) > 0 {
|
if len(warnings) > 0 {
|
||||||
|
@ -203,12 +209,12 @@ func TestBuilderPrepare_SizeID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SizeID != 67 {
|
if b.config.Size != expected {
|
||||||
t.Errorf("invalid: %d", b.config.SizeID)
|
t.Errorf("found %s, expected %s", b.config.Size, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBuilderPrepare_ImageID(t *testing.T) {
|
func TestBuilderPrepare_Image(t *testing.T) {
|
||||||
var b Builder
|
var b Builder
|
||||||
config := testConfig()
|
config := testConfig()
|
||||||
|
|
||||||
|
@ -221,12 +227,15 @@ func TestBuilderPrepare_ImageID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SizeID != 66 {
|
if b.config.Image != DefaultImage {
|
||||||
t.Errorf("invalid: %d", b.config.SizeID)
|
t.Errorf("found %s, expected %s", b.config.Image, DefaultImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expected := "ubuntu-14-04-x64"
|
||||||
|
|
||||||
// Test set
|
// Test set
|
||||||
config["size_id"] = 2
|
config["image_id"] = 0
|
||||||
|
config["image"] = expected
|
||||||
b = Builder{}
|
b = Builder{}
|
||||||
warnings, err = b.Prepare(config)
|
warnings, err = b.Prepare(config)
|
||||||
if len(warnings) > 0 {
|
if len(warnings) > 0 {
|
||||||
|
@ -236,8 +245,8 @@ func TestBuilderPrepare_ImageID(t *testing.T) {
|
||||||
t.Fatalf("should not have error: %s", err)
|
t.Fatalf("should not have error: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if b.config.SizeID != 2 {
|
if b.config.Image != expected {
|
||||||
t.Errorf("invalid: %d", b.config.SizeID)
|
t.Errorf("found %s, expected %s", b.config.Image, expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ func (s *stepCreateDroplet) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
ui.Say("Creating droplet...")
|
ui.Say("Creating droplet...")
|
||||||
|
|
||||||
// Create the droplet based on configuration
|
// Create the droplet based on configuration
|
||||||
dropletId, err := client.CreateDroplet(c.DropletName, c.SizeID, c.ImageID, c.RegionID, sshKeyId, c.PrivateNetworking)
|
dropletId, err := client.CreateDroplet(c.DropletName, c.Size, c.Image, c.Region, sshKeyId, c.PrivateNetworking)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("Error creating droplet: %s", err)
|
err := fmt.Errorf("Error creating droplet: %s", err)
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (s *stepSnapshot) Run(state multistep.StateBag) multistep.StepAction {
|
||||||
|
|
||||||
state.Put("snapshot_image_id", imageId)
|
state.Put("snapshot_image_id", imageId)
|
||||||
state.Put("snapshot_name", c.SnapshotName)
|
state.Put("snapshot_name", c.SnapshotName)
|
||||||
state.Put("region_id", c.RegionID)
|
state.Put("region", c.Region)
|
||||||
|
|
||||||
return multistep.ActionContinue
|
return multistep.ActionContinue
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,16 +35,30 @@ Required:
|
||||||
|
|
||||||
Optional:
|
Optional:
|
||||||
|
|
||||||
|
* `image` (string) - The name (or slug) of the base image to use. This is the
|
||||||
|
image that will be used to launch a new droplet and provision it. This
|
||||||
|
defaults to 'ubuntu-12-04-x64' which is the slug for "Ubuntu 12.04.4 x64".
|
||||||
|
See https://developers.digitalocean.com/images/ for the accepted image names/slugs.
|
||||||
|
|
||||||
* `image_id` (int) - The ID of the base image to use. This is the image that
|
* `image_id` (int) - The ID of the base image to use. This is the image that
|
||||||
will be used to launch a new droplet and provision it. Defaults to "3101045",
|
will be used to launch a new droplet and provision it.
|
||||||
which happens to be "Ubuntu 12.04.4 x64".
|
This setting is deprecated. Use `image` instead.
|
||||||
|
|
||||||
|
* `region` (string) - The name (or slug) of the region to launch the droplet in.
|
||||||
|
Consequently, this is the region where the snapshot will be available.
|
||||||
|
This defaults to "nyc1", which the slug for "New York 1".
|
||||||
|
See https://developers.digitalocean.com/regions/ for the accepted region names/slugs.
|
||||||
|
|
||||||
* `region_id` (int) - The ID of the region to launch the droplet in. Consequently,
|
* `region_id` (int) - The ID of the region to launch the droplet in. Consequently,
|
||||||
this is the region where the snapshot will be available. This defaults to
|
this is the region where the snapshot will be available.
|
||||||
"1", which is "New York 1".
|
This setting is deprecated. Use `region` instead.
|
||||||
|
|
||||||
* `size_id` (int) - The ID of the droplet size to use. This defaults to "66",
|
* `size` (string) - The name (or slug) of the droplet size to use.
|
||||||
which is the 512MB droplet.
|
This defaults to "512mb", which is the slug for "512MB".
|
||||||
|
See https://developers.digitalocean.com/sizes/ for the accepted size names/slugs.
|
||||||
|
|
||||||
|
* `size_id` (int) - The ID of the droplet size to use.
|
||||||
|
This setting is deprecated. Use `size` instead.
|
||||||
|
|
||||||
* `private_networking` (bool) - Set to `true` to enable private networking
|
* `private_networking` (bool) - Set to `true` to enable private networking
|
||||||
for the droplet being created. This defaults to `false`, or not enabled.
|
for the droplet being created. This defaults to `false`, or not enabled.
|
||||||
|
|
Loading…
Reference in New Issue