provider/google: Support Import of 'google_compute_instance_template'
This commit is contained in:
parent
3fc119923e
commit
fe5d7d1c63
|
@ -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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
@ -15,6 +16,9 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Create: resourceComputeInstanceTemplateCreate,
|
Create: resourceComputeInstanceTemplateCreate,
|
||||||
Read: resourceComputeInstanceTemplateRead,
|
Read: resourceComputeInstanceTemplateRead,
|
||||||
Delete: resourceComputeInstanceTemplateDelete,
|
Delete: resourceComputeInstanceTemplateDelete,
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: schema.ImportStatePassthrough,
|
||||||
|
},
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
|
@ -66,6 +70,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"device_name": &schema.Schema{
|
"device_name": &schema.Schema{
|
||||||
|
@ -90,6 +95,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"source_image": &schema.Schema{
|
"source_image": &schema.Schema{
|
||||||
|
@ -102,12 +108,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"mode": &schema.Schema{
|
"mode": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"source": &schema.Schema{
|
"source": &schema.Schema{
|
||||||
|
@ -120,6 +128,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -179,6 +188,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"subnetwork": &schema.Schema{
|
"subnetwork": &schema.Schema{
|
||||||
|
@ -215,6 +225,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
"region": &schema.Schema{
|
"region": &schema.Schema{
|
||||||
|
@ -226,12 +237,14 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
"scheduling": &schema.Schema{
|
"scheduling": &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"preemptible": &schema.Schema{
|
"preemptible": &schema.Schema{
|
||||||
Type: schema.TypeBool,
|
Type: schema.TypeBool,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Default: false,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -245,6 +258,7 @@ func resourceComputeInstanceTemplate() *schema.Resource {
|
||||||
"on_host_maintenance": &schema.Schema{
|
"on_host_maintenance": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -476,6 +490,7 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
|
||||||
instanceProperties.Scheduling = &compute.Scheduling{}
|
instanceProperties.Scheduling = &compute.Scheduling{}
|
||||||
instanceProperties.Scheduling.OnHostMaintenance = "MIGRATE"
|
instanceProperties.Scheduling.OnHostMaintenance = "MIGRATE"
|
||||||
|
|
||||||
|
// Depreciated fields
|
||||||
if v, ok := d.GetOk("automatic_restart"); ok {
|
if v, ok := d.GetOk("automatic_restart"); ok {
|
||||||
instanceProperties.Scheduling.AutomaticRestart = v.(bool)
|
instanceProperties.Scheduling.AutomaticRestart = v.(bool)
|
||||||
}
|
}
|
||||||
|
@ -570,9 +585,91 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac
|
||||||
return resourceComputeInstanceTemplateRead(d, meta)
|
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 {
|
func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
project, err := getProject(d, config)
|
project, err := getProject(d, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -603,6 +700,36 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{
|
||||||
}
|
}
|
||||||
d.Set("self_link", instanceTemplate.SelfLink)
|
d.Set("self_link", instanceTemplate.SelfLink)
|
||||||
d.Set("name", instanceTemplate.Name)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,8 @@ The `scheduling` block supports:
|
||||||
* `on_host_maintenance` - (Optional) Defines the maintenance behavior for this
|
* `on_host_maintenance` - (Optional) Defines the maintenance behavior for this
|
||||||
instance.
|
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).
|
[here](https://cloud.google.com/compute/docs/instances/preemptible).
|
||||||
|
|
||||||
## Attributes Reference
|
## Attributes Reference
|
||||||
|
|
Loading…
Reference in New Issue