}
			})

			It("returns a DisksSpec with device named /dev/xvdc", func() {
				disksSpec := CreateDisksSpec(1)
				Expect(disksSpec).To(Equal(expectedDisksSpec))
			})
		})
	})

	Describe("#CreateVirtualGuestTemplate", func() {
		var (
			agentID      string
			stemcell     bslcstem.SoftLayerStemcell
			cloudProps   VMCloudProperties
			networks     Networks
			env          Environment
			agentOptions AgentOptions
			expectedVgt  sldatatypes.SoftLayer_Virtual_Guest_Template
		)

		BeforeEach(func() {
			agentID = "fake-agentID"
			stemcell = bslcstem.NewSoftLayerStemcell(1234, "fake-stemcell-uuid", fakestem.FakeStemcellKind, softLayerClient, logger)
			cloudProps = VMCloudProperties{
				StartCpus: 4,
				MaxMemory: 2048,
				Domain:    "fake-domain.com",
				BlockDeviceTemplateGroup: sldatatypes.BlockDeviceTemplateGroup{
					GlobalIdentifier: "fake-uuid",
				},
func resourceSoftLayerVirtualserverCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*Client).virtualGuestService
	if client == nil {
		return fmt.Errorf("The client was nil.")
	}

	dc := datatypes.Datacenter{
		Name: d.Get("region").(string),
	}

	networkComponent := datatypes.NetworkComponents{
		MaxSpeed: d.Get("public_network_speed").(int),
	}

	// Options to be passed to Softlayer API
	opts := datatypes.SoftLayer_Virtual_Guest_Template{
		Hostname:          d.Get("name").(string),
		Domain:            d.Get("domain").(string),
		HourlyBillingFlag: true,
		Datacenter:        dc,
		StartCpus:         d.Get("cpu").(int),
		MaxMemory:         d.Get("ram").(int),
		NetworkComponents: []datatypes.NetworkComponents{networkComponent},
		BlockDevices:      getBlockDevices(d),
	}

	// get image type before doing anything
	image_type := d.Get("image_type").(string)

	// get the image ID
	image := d.Get("image").(string)

	// 'image' value is interpreted depending on the
	// value set on 'image_type'
	if image_type == "template_id" {
		// Set ID of the base image template to be used (if any)
		base_image := datatypes.BlockDeviceTemplateGroup{image}
		opts.BlockDeviceTemplateGroup = &base_image
	} else {
		// Use a stock OS instead for this resource
		opts.OperatingSystemReferenceCode = image
	}

	userData := d.Get("user_data").(string)
	if userData != "" {
		opts.UserData = []datatypes.UserData{
			datatypes.UserData{
				Value: userData,
			},
		}
	}

	// Get configured ssh_keys
	ssh_keys := d.Get("ssh_keys.#").(int)
	if ssh_keys > 0 {
		opts.SshKeys = make([]datatypes.SshKey, 0, ssh_keys)
		for i := 0; i < ssh_keys; i++ {
			key := fmt.Sprintf("ssh_keys.%d", i)
			id := d.Get(key).(int)
			sshKey := datatypes.SshKey{
				Id: id,
			}
			opts.SshKeys = append(opts.SshKeys, sshKey)
		}
	}

	log.Printf("[INFO] Creating virtual machine")

	guest, err := client.CreateObject(opts)

	if err != nil {
		return fmt.Errorf("Error creating virtual server: %s", err)
	}

	d.SetId(fmt.Sprintf("%d", guest.Id))

	log.Printf("[INFO] Virtual Machine ID: %s", d.Id())

	// wait for machine availability
	_, err = WaitForNoActiveTransactions(d, meta)

	if err != nil {
		return fmt.Errorf(
			"Error waiting for virtual machine (%s) to become ready: %s", d.Id(), err)
	}

	_, err = WaitForPublicIpAvailable(d, meta)
	if err != nil {
		return fmt.Errorf(
			"Error waiting for virtual machine (%s) to become ready: %s", d.Id(), err)
	}

	return resourceSoftLayerVirtualserverRead(d, meta)
}
func resourceSoftLayerVirtualGuestCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*Client).virtualGuestService
	if client == nil {
		return fmt.Errorf("The client was nil.")
	}

	dc := datatypes.Datacenter{
		Name: d.Get("region").(string),
	}

	networkComponent := datatypes.NetworkComponents{
		MaxSpeed: d.Get("public_network_speed").(int),
	}

	privateNetworkOnly := d.Get("private_network_only").(bool)
	opts := datatypes.SoftLayer_Virtual_Guest_Template{
		Hostname:               d.Get("name").(string),
		Domain:                 d.Get("domain").(string),
		HourlyBillingFlag:      d.Get("hourly_billing").(bool),
		PrivateNetworkOnlyFlag: privateNetworkOnly,
		Datacenter:             dc,
		StartCpus:              d.Get("cpu").(int),
		MaxMemory:              d.Get("ram").(int),
		NetworkComponents:      []datatypes.NetworkComponents{networkComponent},
		BlockDevices:           getBlockDevices(d),
		LocalDiskFlag:          d.Get("local_disk").(bool),
		PostInstallScriptUri:   d.Get("post_install_script_uri").(string),
	}

	if dedicatedAcctHostOnly, ok := d.GetOk("dedicated_acct_host_only"); ok {
		opts.DedicatedAccountHostOnlyFlag = dedicatedAcctHostOnly.(bool)
	}

	if globalIdentifier, ok := d.GetOk("block_device_template_group_gid"); ok {
		opts.BlockDeviceTemplateGroup = &datatypes.BlockDeviceTemplateGroup{
			GlobalIdentifier: globalIdentifier.(string),
		}
	}

	if operatingSystemReferenceCode, ok := d.GetOk("image"); ok {
		opts.OperatingSystemReferenceCode = operatingSystemReferenceCode.(string)
	}

	// Apply frontend VLAN if provided
	if param, ok := d.GetOk("frontend_vlan_id"); ok {
		frontendVlanId, err := strconv.Atoi(param.(string))
		if err != nil {
			return fmt.Errorf("Not a valid frontend ID, must be an integer: %s", err)
		}
		opts.PrimaryNetworkComponent = &datatypes.PrimaryNetworkComponent{
			NetworkVlan: datatypes.NetworkVlan{Id: (frontendVlanId)},
		}
	}

	// Apply backend VLAN if provided
	if param, ok := d.GetOk("backend_vlan_id"); ok {
		backendVlanId, err := strconv.Atoi(param.(string))
		if err != nil {
			return fmt.Errorf("Not a valid backend ID, must be an integer: %s", err)
		}
		opts.PrimaryBackendNetworkComponent = &datatypes.PrimaryBackendNetworkComponent{
			NetworkVlan: datatypes.NetworkVlan{Id: (backendVlanId)},
		}
	}

	if userData, ok := d.GetOk("user_data"); ok {
		opts.UserData = []datatypes.UserData{
			datatypes.UserData{
				Value: userData.(string),
			},
		}
	}

	// Get configured ssh_keys
	ssh_keys := d.Get("ssh_keys.#").(int)
	if ssh_keys > 0 {
		opts.SshKeys = make([]datatypes.SshKey, 0, ssh_keys)
		for i := 0; i < ssh_keys; i++ {
			key := fmt.Sprintf("ssh_keys.%d", i)
			id := d.Get(key).(int)
			sshKey := datatypes.SshKey{
				Id: id,
			}
			opts.SshKeys = append(opts.SshKeys, sshKey)
		}
	}

	log.Printf("[INFO] Creating virtual machine")

	guest, err := client.CreateObject(opts)

	if err != nil {
		return fmt.Errorf("Error creating virtual guest: %s", err)
	}

	d.SetId(fmt.Sprintf("%d", guest.Id))

	log.Printf("[INFO] Virtual Machine ID: %s", d.Id())

	// wait for machine availability
	_, err = WaitForNoActiveTransactions(d, meta)

	if err != nil {
		return fmt.Errorf(
			"Error waiting for virtual machine (%s) to become ready: %s", d.Id(), err)
	}

	if !privateNetworkOnly {
		_, err = WaitForPublicIpAvailable(d, meta)
		if err != nil {
			return fmt.Errorf(
				"Error waiting for virtual machine (%s) public ip to become ready: %s", d.Id(), err)
		}
	}

	return resourceSoftLayerVirtualGuestRead(d, meta)
}