Merge pull request #8147 from nwwebb/import-instance-template
provider/google: Support Import of 'google_compute_instance_template'
This commit is contained in:
commit
23ab7ee6bb
|
@ -0,0 +1,114 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
)
|
||||
|
||||
func TestAccComputeInstanceTemplate_importBasic(t *testing.T) {
|
||||
resourceName := "google_compute_instance_template.foobar"
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstanceTemplate_basic,
|
||||
},
|
||||
|
||||
resource.TestStep{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstanceTemplate_importIp(t *testing.T) {
|
||||
resourceName := "google_compute_instance_template.foobar"
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstanceTemplate_ip,
|
||||
},
|
||||
|
||||
resource.TestStep{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstanceTemplate_importDisks(t *testing.T) {
|
||||
resourceName := "google_compute_instance_template.foobar"
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstanceTemplate_disks,
|
||||
},
|
||||
|
||||
resource.TestStep{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstanceTemplate_importSubnetAuto(t *testing.T) {
|
||||
resourceName := "google_compute_instance_template.foobar"
|
||||
network := "network-" + acctest.RandString(10)
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstanceTemplate_subnet_auto(network),
|
||||
},
|
||||
|
||||
resource.TestStep{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccComputeInstanceTemplate_importSubnetCustom(t *testing.T) {
|
||||
resourceName := "google_compute_instance_template.foobar"
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccComputeInstanceTemplate_subnet_custom,
|
||||
},
|
||||
|
||||
resource.TestStep{
|
||||
ResourceName: resourceName,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -3,6 +3,7 @@ package google
|
|||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
|
@ -15,6 +16,9 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Create: resourceComputeInstanceTemplateCreate,
|
||||
Read: resourceComputeInstanceTemplateRead,
|
||||
Delete: resourceComputeInstanceTemplateDelete,
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
|
@ -66,6 +70,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"device_name": &schema.Schema{
|
||||
|
@ -90,6 +95,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"source_image": &schema.Schema{
|
||||
|
@ -102,12 +108,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"mode": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"source": &schema.Schema{
|
||||
|
@ -120,6 +128,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -179,6 +188,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"subnetwork": &schema.Schema{
|
||||
|
@ -215,6 +225,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"region": &schema.Schema{
|
||||
|
@ -226,12 +237,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
"scheduling": &schema.Schema{
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"preemptible": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
|
@ -245,6 +258,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
|||
"on_host_maintenance": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
},
|
||||
|
@ -476,6 +490,7 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
|
|||
instanceProperties.Scheduling = &compute.Scheduling{}
|
||||
instanceProperties.Scheduling.OnHostMaintenance = "MIGRATE"
|
||||
|
||||
// Depreciated fields
|
||||
if v, ok := d.GetOk("automatic_restart"); ok {
|
||||
instanceProperties.Scheduling.AutomaticRestart = v.(bool)
|
||||
}
|
||||
|
@ -570,9 +585,91 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
|
|||
return resourceComputeInstanceTemplateRead(d, meta)
|
||||
}
|
||||
|
||||
func flattenDisks(disks []*compute.AttachedDisk) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, len(disks))
|
||||
for _, disk := range disks {
|
||||
diskMap := make(map[string]interface{})
|
||||
if disk.InitializeParams != nil {
|
||||
sourceImageUrl := strings.Split(disk.InitializeParams.SourceImage, "/")
|
||||
diskMap["source_image"] = sourceImageUrl[len(sourceImageUrl)-1]
|
||||
diskMap["disk_type"] = disk.InitializeParams.DiskType
|
||||
diskMap["disk_name"] = disk.InitializeParams.DiskName
|
||||
diskMap["disk_size_gb"] = disk.InitializeParams.DiskSizeGb
|
||||
}
|
||||
diskMap["auto_delete"] = disk.AutoDelete
|
||||
diskMap["boot"] = disk.Boot
|
||||
diskMap["device_name"] = disk.DeviceName
|
||||
diskMap["interface"] = disk.Interface
|
||||
diskMap["source"] = disk.Source
|
||||
diskMap["mode"] = disk.Mode
|
||||
diskMap["type"] = disk.Type
|
||||
result = append(result, diskMap)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenNetworkInterfaces(networkInterfaces []*compute.NetworkInterface) ([]map[string]interface{}, string) {
|
||||
result := make([]map[string]interface{}, 0, len(networkInterfaces))
|
||||
region := ""
|
||||
for _, networkInterface := range networkInterfaces {
|
||||
networkInterfaceMap := make(map[string]interface{})
|
||||
if networkInterface.Network != "" {
|
||||
networkUrl := strings.Split(networkInterface.Network, "/")
|
||||
networkInterfaceMap["network"] = networkUrl[len(networkUrl)-1]
|
||||
}
|
||||
if networkInterface.Subnetwork != "" {
|
||||
subnetworkUrl := strings.Split(networkInterface.Subnetwork, "/")
|
||||
networkInterfaceMap["subnetwork"] = subnetworkUrl[len(subnetworkUrl)-1]
|
||||
region = subnetworkUrl[len(subnetworkUrl)-3]
|
||||
}
|
||||
|
||||
if networkInterface.AccessConfigs != nil {
|
||||
accessConfigsMap := make([]map[string]interface{}, 0, len(networkInterface.AccessConfigs))
|
||||
for _, accessConfig := range networkInterface.AccessConfigs {
|
||||
accessConfigMap := make(map[string]interface{})
|
||||
accessConfigMap["nat_ip"] = accessConfig.NatIP
|
||||
|
||||
accessConfigsMap = append(accessConfigsMap, accessConfigMap)
|
||||
}
|
||||
networkInterfaceMap["access_config"] = accessConfigsMap
|
||||
}
|
||||
result = append(result, networkInterfaceMap)
|
||||
}
|
||||
return result, region
|
||||
}
|
||||
|
||||
func flattenScheduling(scheduling *compute.Scheduling) ([]map[string]interface{}, bool) {
|
||||
result := make([]map[string]interface{}, 0, 1)
|
||||
schedulingMap := make(map[string]interface{})
|
||||
schedulingMap["automatic_restart"] = scheduling.AutomaticRestart
|
||||
schedulingMap["on_host_maintenance"] = scheduling.OnHostMaintenance
|
||||
schedulingMap["preemptible"] = scheduling.Preemptible
|
||||
result = append(result, schedulingMap)
|
||||
return result, scheduling.AutomaticRestart
|
||||
}
|
||||
|
||||
func flattenServiceAccounts(serviceAccounts []*compute.ServiceAccount) []map[string]interface{} {
|
||||
result := make([]map[string]interface{}, 0, len(serviceAccounts))
|
||||
for _, serviceAccount := range serviceAccounts {
|
||||
serviceAccountMap := make(map[string]interface{})
|
||||
serviceAccountMap["email"] = serviceAccount.Email
|
||||
serviceAccountMap["scopes"] = serviceAccount.Scopes
|
||||
|
||||
result = append(result, serviceAccountMap)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenMetadata(metadata *compute.Metadata) map[string]string {
|
||||
metadataMap := make(map[string]string)
|
||||
for _, item := range metadata.Items {
|
||||
metadataMap[item.Key] = *item.Value
|
||||
}
|
||||
return metadataMap
|
||||
}
|
||||
|
||||
func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{}) error {
|
||||
config := meta.(*Config)
|
||||
|
||||
project, err := getProject(d, config)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -603,6 +700,36 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{
|
|||
}
|
||||
d.Set("self_link", instanceTemplate.SelfLink)
|
||||
d.Set("name", instanceTemplate.Name)
|
||||
if instanceTemplate.Properties.Disks != nil {
|
||||
d.Set("disk", flattenDisks(instanceTemplate.Properties.Disks))
|
||||
}
|
||||
d.Set("description", instanceTemplate.Description)
|
||||
d.Set("machine_type", instanceTemplate.Properties.MachineType)
|
||||
d.Set("can_ip_forward", instanceTemplate.Properties.CanIpForward)
|
||||
if instanceTemplate.Properties.Metadata != nil {
|
||||
d.Set("metadata", flattenMetadata(instanceTemplate.Properties.Metadata))
|
||||
}
|
||||
d.Set("instance_description", instanceTemplate.Properties.Description)
|
||||
d.Set("project", project)
|
||||
if instanceTemplate.Properties.NetworkInterfaces != nil {
|
||||
networkInterfaces, region := flattenNetworkInterfaces(instanceTemplate.Properties.NetworkInterfaces)
|
||||
d.Set("network_interface", networkInterfaces)
|
||||
// region is where to look up the subnetwork if there is one attached to the instance template
|
||||
if region != "" {
|
||||
d.Set("region", region)
|
||||
}
|
||||
}
|
||||
if instanceTemplate.Properties.Scheduling != nil {
|
||||
scheduling, autoRestart := flattenScheduling(instanceTemplate.Properties.Scheduling)
|
||||
d.Set("scheduling", scheduling)
|
||||
d.Set("automatic_restart", autoRestart)
|
||||
}
|
||||
if instanceTemplate.Properties.Tags != nil {
|
||||
d.Set("tags", instanceTemplate.Properties.Tags.Items)
|
||||
}
|
||||
if instanceTemplate.Properties.ServiceAccounts != nil {
|
||||
d.Set("service_account", flattenServiceAccounts(instanceTemplate.Properties.ServiceAccounts))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,8 @@ The `scheduling` block supports:
|
|||
* `on_host_maintenance` - (Optional) Defines the maintenance behavior for this
|
||||
instance.
|
||||
|
||||
* `preemptible` - (Optional) Allows instance to be preempted. Read more on this
|
||||
* `preemptible` - (Optional) Allows instance to be preempted. This defaults to
|
||||
false. Read more on this
|
||||
[here](https://cloud.google.com/compute/docs/instances/preemptible).
|
||||
|
||||
## Attributes Reference
|
||||
|
|
Loading…
Reference in New Issue