mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-01 16:21:06 +00:00
Add compute node types and templates (#3446)
Signed-off-by: Modular Magician <magic-modules@google.com>
This commit is contained in:
parent
9eff6af8f6
commit
8077953aa7
71
google/data_source_google_compute_node_types.go
Normal file
71
google/data_source_google_compute_node_types.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"sort"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceGoogleComputeNodeTypes() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Read: dataSourceGoogleComputeNodeTypesRead,
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"project": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"zone": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"names": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func dataSourceGoogleComputeNodeTypesRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
zone, err := getZone(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Please specify zone to get appropriate node types for zone. Unable to get zone: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := config.clientCompute.NodeTypes.List(project, zone).Do()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
nodeTypes := flattenComputeNodeTypes(resp.Items)
|
||||||
|
log.Printf("[DEBUG] Received Google Compute Regions: %q", nodeTypes)
|
||||||
|
|
||||||
|
d.Set("names", nodeTypes)
|
||||||
|
d.Set("project", project)
|
||||||
|
d.Set("zone", zone)
|
||||||
|
d.SetId(time.Now().UTC().String())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTypes(nodeTypes []*compute.NodeType) []string {
|
||||||
|
result := make([]string, len(nodeTypes), len(nodeTypes))
|
||||||
|
for i, nodeType := range nodeTypes {
|
||||||
|
result[i] = nodeType.Name
|
||||||
|
}
|
||||||
|
sort.Strings(result)
|
||||||
|
return result
|
||||||
|
}
|
74
google/data_source_google_compute_node_types_test.go
Normal file
74
google/data_source_google_compute_node_types_test.go
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccDataSourceComputeNodeTypes_basic(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccDataSourceComputeNodeTypes_basic,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGoogleComputeNodeTypes("data.google_compute_node_types.available"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckGoogleComputeNodeTypes(n string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Can't find node types data source: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return errors.New("node types data source ID not set.")
|
||||||
|
}
|
||||||
|
|
||||||
|
count, ok := rs.Primary.Attributes["names.#"]
|
||||||
|
if !ok {
|
||||||
|
return errors.New("can't find 'names' attribute")
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt, err := strconv.Atoi(count)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("failed to read number of node types")
|
||||||
|
}
|
||||||
|
if cnt < 1 {
|
||||||
|
return fmt.Errorf("expected at least one node type, got %d", cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < cnt; i++ {
|
||||||
|
idx := fmt.Sprintf("names.%d", i)
|
||||||
|
v, ok := rs.Primary.Attributes[idx]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected %q, version not found", idx)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !regexp.MustCompile(`-[0-9]+-[0-9]+$`).MatchString(v) {
|
||||||
|
return fmt.Errorf("unexpected type format for %q, value is %v", idx, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var testAccDataSourceComputeNodeTypes_basic = `
|
||||||
|
data "google_compute_node_types" "available" {
|
||||||
|
zone = "us-central1-a"
|
||||||
|
}
|
||||||
|
`
|
@ -93,6 +93,7 @@ func Provider() terraform.ResourceProvider {
|
|||||||
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
|
"google_compute_instance_group": dataSourceGoogleComputeInstanceGroup(),
|
||||||
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
|
"google_compute_lb_ip_ranges": dataSourceGoogleComputeLbIpRanges(),
|
||||||
"google_compute_network": dataSourceGoogleComputeNetwork(),
|
"google_compute_network": dataSourceGoogleComputeNetwork(),
|
||||||
|
"google_compute_node_types": dataSourceGoogleComputeNodeTypes(),
|
||||||
"google_compute_regions": dataSourceGoogleComputeRegions(),
|
"google_compute_regions": dataSourceGoogleComputeRegions(),
|
||||||
"google_compute_region_instance_group": dataSourceGoogleComputeRegionInstanceGroup(),
|
"google_compute_region_instance_group": dataSourceGoogleComputeRegionInstanceGroup(),
|
||||||
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
|
"google_compute_subnetwork": dataSourceGoogleComputeSubnetwork(),
|
||||||
|
@ -33,6 +33,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{
|
|||||||
"google_compute_image": resourceComputeImage(),
|
"google_compute_image": resourceComputeImage(),
|
||||||
"google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(),
|
"google_compute_interconnect_attachment": resourceComputeInterconnectAttachment(),
|
||||||
"google_compute_network": resourceComputeNetwork(),
|
"google_compute_network": resourceComputeNetwork(),
|
||||||
|
"google_compute_node_template": resourceComputeNodeTemplate(),
|
||||||
"google_compute_region_autoscaler": resourceComputeRegionAutoscaler(),
|
"google_compute_region_autoscaler": resourceComputeRegionAutoscaler(),
|
||||||
"google_compute_region_disk": resourceComputeRegionDisk(),
|
"google_compute_region_disk": resourceComputeRegionDisk(),
|
||||||
"google_compute_route": resourceComputeRoute(),
|
"google_compute_route": resourceComputeRoute(),
|
||||||
|
431
google/resource_compute_node_template.go
Normal file
431
google/resource_compute_node_template.go
Normal file
@ -0,0 +1,431 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"reflect"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"google.golang.org/api/compute/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceComputeNodeTemplate() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Create: resourceComputeNodeTemplateCreate,
|
||||||
|
Read: resourceComputeNodeTemplateRead,
|
||||||
|
Delete: resourceComputeNodeTemplateDelete,
|
||||||
|
|
||||||
|
Importer: &schema.ResourceImporter{
|
||||||
|
State: resourceComputeNodeTemplateImport,
|
||||||
|
},
|
||||||
|
|
||||||
|
Timeouts: &schema.ResourceTimeout{
|
||||||
|
Create: schema.DefaultTimeout(240 * time.Second),
|
||||||
|
Delete: schema.DefaultTimeout(240 * time.Second),
|
||||||
|
},
|
||||||
|
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"description": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"node_affinity_labels": {
|
||||||
|
Type: schema.TypeMap,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
"node_type": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"node_type_flexibility"},
|
||||||
|
},
|
||||||
|
"node_type_flexibility": {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"cpus": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"memory": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"local_ssd": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ConflictsWith: []string{"node_type"},
|
||||||
|
},
|
||||||
|
"region": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||||
|
},
|
||||||
|
"creation_timestamp": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"project": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
},
|
||||||
|
"self_link": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeNodeTemplateCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
obj := make(map[string]interface{})
|
||||||
|
descriptionProp, err := expandComputeNodeTemplateDescription(d.Get("description"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
|
||||||
|
obj["description"] = descriptionProp
|
||||||
|
}
|
||||||
|
nameProp, err := expandComputeNodeTemplateName(d.Get("name"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
|
||||||
|
obj["name"] = nameProp
|
||||||
|
}
|
||||||
|
nodeAffinityLabelsProp, err := expandComputeNodeTemplateNodeAffinityLabels(d.Get("node_affinity_labels"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("node_affinity_labels"); !isEmptyValue(reflect.ValueOf(nodeAffinityLabelsProp)) && (ok || !reflect.DeepEqual(v, nodeAffinityLabelsProp)) {
|
||||||
|
obj["nodeAffinityLabels"] = nodeAffinityLabelsProp
|
||||||
|
}
|
||||||
|
nodeTypeProp, err := expandComputeNodeTemplateNodeType(d.Get("node_type"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("node_type"); !isEmptyValue(reflect.ValueOf(nodeTypeProp)) && (ok || !reflect.DeepEqual(v, nodeTypeProp)) {
|
||||||
|
obj["nodeType"] = nodeTypeProp
|
||||||
|
}
|
||||||
|
nodeTypeFlexibilityProp, err := expandComputeNodeTemplateNodeTypeFlexibility(d.Get("node_type_flexibility"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("node_type_flexibility"); !isEmptyValue(reflect.ValueOf(nodeTypeFlexibilityProp)) && (ok || !reflect.DeepEqual(v, nodeTypeFlexibilityProp)) {
|
||||||
|
obj["nodeTypeFlexibility"] = nodeTypeFlexibilityProp
|
||||||
|
}
|
||||||
|
regionProp, err := expandComputeNodeTemplateRegion(d.Get("region"), d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
} else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) {
|
||||||
|
obj["region"] = regionProp
|
||||||
|
}
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Creating new NodeTemplate: %#v", obj)
|
||||||
|
res, err := sendRequestWithTimeout(config, "POST", url, obj, d.Timeout(schema.TimeoutCreate))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error creating NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the ID now
|
||||||
|
id, err := replaceVars(d, config, "{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error constructing id: %s", err)
|
||||||
|
}
|
||||||
|
d.SetId(id)
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op := &compute.Operation{}
|
||||||
|
err = Convert(res, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
waitErr := computeOperationWaitTime(
|
||||||
|
config.clientCompute, op, project, "Creating NodeTemplate",
|
||||||
|
int(d.Timeout(schema.TimeoutCreate).Minutes()))
|
||||||
|
|
||||||
|
if waitErr != nil {
|
||||||
|
// The resource didn't actually create
|
||||||
|
d.SetId("")
|
||||||
|
return fmt.Errorf("Error waiting to create NodeTemplate: %s", waitErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Finished creating NodeTemplate %q: %#v", d.Id(), res)
|
||||||
|
|
||||||
|
return resourceComputeNodeTemplateRead(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeNodeTemplateRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := sendRequest(config, "GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return handleNotFoundError(err, d, fmt.Sprintf("ComputeNodeTemplate %q", d.Id()))
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := d.Set("project", project); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d.Set("creation_timestamp", flattenComputeNodeTemplateCreationTimestamp(res["creationTimestamp"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("description", flattenComputeNodeTemplateDescription(res["description"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("name", flattenComputeNodeTemplateName(res["name"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("node_affinity_labels", flattenComputeNodeTemplateNodeAffinityLabels(res["nodeAffinityLabels"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("node_type", flattenComputeNodeTemplateNodeType(res["nodeType"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("node_type_flexibility", flattenComputeNodeTemplateNodeTypeFlexibility(res["nodeTypeFlexibility"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("region", flattenComputeNodeTemplateRegion(res["region"], d)); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil {
|
||||||
|
return fmt.Errorf("Error reading NodeTemplate: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeNodeTemplateDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var obj map[string]interface{}
|
||||||
|
log.Printf("[DEBUG] Deleting NodeTemplate %q", d.Id())
|
||||||
|
res, err := sendRequestWithTimeout(config, "DELETE", url, obj, d.Timeout(schema.TimeoutDelete))
|
||||||
|
if err != nil {
|
||||||
|
return handleNotFoundError(err, d, "NodeTemplate")
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
op := &compute.Operation{}
|
||||||
|
err = Convert(res, op)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = computeOperationWaitTime(
|
||||||
|
config.clientCompute, op, project, "Deleting NodeTemplate",
|
||||||
|
int(d.Timeout(schema.TimeoutDelete).Minutes()))
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] Finished deleting NodeTemplate %q: %#v", d.Id(), res)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceComputeNodeTemplateImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
|
||||||
|
config := meta.(*Config)
|
||||||
|
if err := parseImportId([]string{"projects/(?P<project>[^/]+)/regions/(?P<region>[^/]+)/nodeTemplates/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<region>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace import id for the resource id
|
||||||
|
id, err := replaceVars(d, config, "{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error constructing id: %s", err)
|
||||||
|
}
|
||||||
|
d.SetId(id)
|
||||||
|
|
||||||
|
return []*schema.ResourceData{d}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateCreationTimestamp(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateDescription(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateName(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateNodeAffinityLabels(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateNodeType(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateNodeTypeFlexibility(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
original := v.(map[string]interface{})
|
||||||
|
if len(original) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
transformed := make(map[string]interface{})
|
||||||
|
transformed["cpus"] =
|
||||||
|
flattenComputeNodeTemplateNodeTypeFlexibilityCpus(original["cpus"], d)
|
||||||
|
transformed["memory"] =
|
||||||
|
flattenComputeNodeTemplateNodeTypeFlexibilityMemory(original["memory"], d)
|
||||||
|
transformed["local_ssd"] =
|
||||||
|
flattenComputeNodeTemplateNodeTypeFlexibilityLocalSsd(original["localSsd"], d)
|
||||||
|
return []interface{}{transformed}
|
||||||
|
}
|
||||||
|
func flattenComputeNodeTemplateNodeTypeFlexibilityCpus(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateNodeTypeFlexibilityMemory(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateNodeTypeFlexibilityLocalSsd(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenComputeNodeTemplateRegion(v interface{}, d *schema.ResourceData) interface{} {
|
||||||
|
if v == nil {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
return NameFromSelfLinkStateFunc(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateDescription(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateName(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeAffinityLabels(v interface{}, d TerraformResourceData, config *Config) (map[string]string, error) {
|
||||||
|
if v == nil {
|
||||||
|
return map[string]string{}, nil
|
||||||
|
}
|
||||||
|
m := make(map[string]string)
|
||||||
|
for k, val := range v.(map[string]interface{}) {
|
||||||
|
m[k] = val.(string)
|
||||||
|
}
|
||||||
|
return m, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeType(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeTypeFlexibility(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
l := v.([]interface{})
|
||||||
|
if len(l) == 0 || l[0] == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
raw := l[0]
|
||||||
|
original := raw.(map[string]interface{})
|
||||||
|
transformed := make(map[string]interface{})
|
||||||
|
|
||||||
|
transformedCpus, err := expandComputeNodeTemplateNodeTypeFlexibilityCpus(original["cpus"], d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if val := reflect.ValueOf(transformedCpus); val.IsValid() && !isEmptyValue(val) {
|
||||||
|
transformed["cpus"] = transformedCpus
|
||||||
|
}
|
||||||
|
|
||||||
|
transformedMemory, err := expandComputeNodeTemplateNodeTypeFlexibilityMemory(original["memory"], d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if val := reflect.ValueOf(transformedMemory); val.IsValid() && !isEmptyValue(val) {
|
||||||
|
transformed["memory"] = transformedMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
transformedLocalSsd, err := expandComputeNodeTemplateNodeTypeFlexibilityLocalSsd(original["local_ssd"], d, config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else if val := reflect.ValueOf(transformedLocalSsd); val.IsValid() && !isEmptyValue(val) {
|
||||||
|
transformed["localSsd"] = transformedLocalSsd
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformed, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeTypeFlexibilityCpus(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeTypeFlexibilityMemory(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateNodeTypeFlexibilityLocalSsd(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandComputeNodeTemplateRegion(v interface{}, d TerraformResourceData, config *Config) (interface{}, error) {
|
||||||
|
f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Invalid value for region: %s", err)
|
||||||
|
}
|
||||||
|
return f.RelativeLink(), nil
|
||||||
|
}
|
93
google/resource_compute_node_template_generated_test.go
Normal file
93
google/resource_compute_node_template_generated_test.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This file is automatically generated by Magic Modules and manual
|
||||||
|
// changes will be clobbered when the file is regenerated.
|
||||||
|
//
|
||||||
|
// Please read more about how to change this file in
|
||||||
|
// .github/CONTRIBUTING.md.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
package google
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform/terraform"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccComputeNodeTemplate_nodeTemplateBasicExample(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
context := map[string]interface{}{
|
||||||
|
"random_suffix": acctest.RandString(10),
|
||||||
|
}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckComputeNodeTemplateDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccComputeNodeTemplate_nodeTemplateBasicExample(context),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceName: "google_compute_node_template.template",
|
||||||
|
ImportState: true,
|
||||||
|
ImportStateVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccComputeNodeTemplate_nodeTemplateBasicExample(context map[string]interface{}) string {
|
||||||
|
return Nprintf(`
|
||||||
|
data "google_compute_node_types" "central1a" {
|
||||||
|
zone = "us-central1-a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_node_template" "template" {
|
||||||
|
name = "soletenant-tmpl-%{random_suffix}"
|
||||||
|
region = "us-central1"
|
||||||
|
|
||||||
|
node_affinity_labels = {
|
||||||
|
foo = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
node_type = "${data.google_compute_node_types.central1a.names[0]}"
|
||||||
|
}
|
||||||
|
`, context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeNodeTemplateDestroy(s *terraform.State) error {
|
||||||
|
for name, rs := range s.RootModule().Resources {
|
||||||
|
if rs.Type != "google_compute_node_template" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(name, "data.") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
|
url, err := replaceVarsForTest(rs, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = sendRequest(config, "GET", url, nil)
|
||||||
|
if err == nil {
|
||||||
|
return fmt.Errorf("ComputeNodeTemplate still exists at %s", url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
44
website/docs/d/google_compute_node_types.html.markdown
Normal file
44
website/docs/d/google_compute_node_types.html.markdown
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
layout: "google"
|
||||||
|
page_title: "Google: google_compute_node_types"
|
||||||
|
sidebar_current: "docs-google-datasource-compute-node-types"
|
||||||
|
description: |-
|
||||||
|
Provides list of available Google Compute Engine node types for
|
||||||
|
sole-tenant nodes.
|
||||||
|
---
|
||||||
|
|
||||||
|
# google\_compute\_node\_types
|
||||||
|
|
||||||
|
Provides available node types for Compute Engine sole-tenant nodes in a zone
|
||||||
|
for a given project. For more information, see [the official documentation](https://cloud.google.com/compute/docs/nodes/#types) and [API](https://cloud.google.com/compute/docs/reference/rest/v1/nodeTypes).
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
data "google_compute_node_types" "central1b" {
|
||||||
|
zone = "us-central1-b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_node_template" "tmpl" {
|
||||||
|
name = "terraform-test-tmpl"
|
||||||
|
region = "us-central1"
|
||||||
|
node_type = "${data.google_compute_node_types.types.names[0]}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
* `zone` (Optional) - The zone to list node types for. Should be in zone of intended node groups and region of referencing node template. If `zone` is not specified, the provider-level zone must be set and is used
|
||||||
|
instead.
|
||||||
|
|
||||||
|
* `project` (Optional) - ID of the project to list available node types for.
|
||||||
|
Should match the project the nodes of this type will be deployed to.
|
||||||
|
Defaults to the project that the provider is authenticated with.
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
The following attributes are exported:
|
||||||
|
|
||||||
|
* `names` - A list of node types available in the given zone and project.
|
144
website/docs/r/compute_node_template.html.markdown
Normal file
144
website/docs/r/compute_node_template.html.markdown
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
---
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# This file is automatically generated by Magic Modules and manual
|
||||||
|
# changes will be clobbered when the file is regenerated.
|
||||||
|
#
|
||||||
|
# Please read more about how to change this file in
|
||||||
|
# .github/CONTRIBUTING.md.
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
layout: "google"
|
||||||
|
page_title: "Google: google_compute_node_template"
|
||||||
|
sidebar_current: "docs-google-compute-node-template"
|
||||||
|
description: |-
|
||||||
|
Represents a NodeTemplate resource.
|
||||||
|
---
|
||||||
|
|
||||||
|
# google\_compute\_node\_template
|
||||||
|
|
||||||
|
Represents a NodeTemplate resource. Node templates specify properties
|
||||||
|
for creating sole-tenant nodes, such as node type, vCPU and memory
|
||||||
|
requirments, node affinity labels, and region.
|
||||||
|
|
||||||
|
|
||||||
|
To get more information about NodeTemplate, see:
|
||||||
|
|
||||||
|
* [API documentation](https://cloud.google.com/compute/docs/reference/rest/v1/nodeTemplates)
|
||||||
|
* How-to Guides
|
||||||
|
* [Sole-Tenant Nodes](https://cloud.google.com/compute/docs/nodes/)
|
||||||
|
|
||||||
|
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
|
||||||
|
<a href="https://console.cloud.google.com/cloudshell/open?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fdocs-examples.git&cloudshell_working_dir=node_template_basic&cloudshell_image=gcr.io%2Fgraphite-cloud-shell-images%2Fterraform%3Alatest&open_in_editor=main.tf&cloudshell_print=.%2Fmotd&cloudshell_tutorial=.%2Ftutorial.md" target="_blank">
|
||||||
|
<img alt="Open in Cloud Shell" src="//gstatic.com/cloudssh/images/open-btn.svg" style="max-height: 44px; margin: 32px auto; max-width: 100%;">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
## Example Usage - Node Template Basic
|
||||||
|
|
||||||
|
|
||||||
|
```hcl
|
||||||
|
data "google_compute_node_types" "central1a" {
|
||||||
|
zone = "us-central1-a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_node_template" "template" {
|
||||||
|
name = "soletenant-tmpl"
|
||||||
|
region = "us-central1"
|
||||||
|
|
||||||
|
node_affinity_labels = {
|
||||||
|
foo = "baz"
|
||||||
|
}
|
||||||
|
|
||||||
|
node_type = "${data.google_compute_node_types.central1a.names[0]}"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
The following arguments are supported:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
- - -
|
||||||
|
|
||||||
|
|
||||||
|
* `description` -
|
||||||
|
(Optional)
|
||||||
|
An optional textual description of the resource.
|
||||||
|
|
||||||
|
* `name` -
|
||||||
|
(Optional)
|
||||||
|
Name of the resource.
|
||||||
|
|
||||||
|
* `node_affinity_labels` -
|
||||||
|
(Optional)
|
||||||
|
Labels to use for node affinity, which will be used in
|
||||||
|
instance scheduling.
|
||||||
|
|
||||||
|
* `node_type` -
|
||||||
|
(Optional)
|
||||||
|
Node type to use for nodes group that are created from this template.
|
||||||
|
Only one of nodeTypeFlexibility and nodeType can be specified.
|
||||||
|
|
||||||
|
* `node_type_flexibility` -
|
||||||
|
(Optional)
|
||||||
|
Flexible properties for the desired node type. Node groups that
|
||||||
|
use this node template will create nodes of a type that matches
|
||||||
|
these properties. Only one of nodeTypeFlexibility and nodeType can
|
||||||
|
be specified. Structure is documented below.
|
||||||
|
|
||||||
|
* `region` -
|
||||||
|
(Optional)
|
||||||
|
Region where nodes using the node template will be created.
|
||||||
|
If it is not provided, the provider region is used.
|
||||||
|
* `project` - (Optional) The ID of the project in which the resource belongs.
|
||||||
|
If it is not provided, the provider project is used.
|
||||||
|
|
||||||
|
|
||||||
|
The `node_type_flexibility` block supports:
|
||||||
|
|
||||||
|
* `cpus` -
|
||||||
|
(Optional)
|
||||||
|
Number of virtual CPUs to use.
|
||||||
|
|
||||||
|
* `memory` -
|
||||||
|
(Optional)
|
||||||
|
Physical memory available to the node, defined in MB.
|
||||||
|
|
||||||
|
* `local_ssd` -
|
||||||
|
Use local SSD
|
||||||
|
|
||||||
|
## Attributes Reference
|
||||||
|
|
||||||
|
In addition to the arguments listed above, the following computed attributes are exported:
|
||||||
|
|
||||||
|
|
||||||
|
* `creation_timestamp` -
|
||||||
|
Creation timestamp in RFC3339 text format.
|
||||||
|
* `self_link` - The URI of the created resource.
|
||||||
|
|
||||||
|
|
||||||
|
## Timeouts
|
||||||
|
|
||||||
|
This resource provides the following
|
||||||
|
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
|
||||||
|
|
||||||
|
- `create` - Default is 4 minutes.
|
||||||
|
- `delete` - Default is 4 minutes.
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
NodeTemplate can be imported using any of these accepted formats:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ terraform import google_compute_node_template.default projects/{{project}}/regions/{{region}}/nodeTemplates/{{name}}
|
||||||
|
$ terraform import google_compute_node_template.default {{project}}/{{region}}/{{name}}
|
||||||
|
$ terraform import google_compute_node_template.default {{name}}
|
||||||
|
```
|
||||||
|
|
||||||
|
-> If you're importing a resource with beta features, make sure to include `-provider=google-beta`
|
||||||
|
as an argument so that Terraform uses the correct provider to import your resource.
|
@ -84,6 +84,9 @@
|
|||||||
<li<%= sidebar_current("docs-google-datasource-project-services") %>>
|
<li<%= sidebar_current("docs-google-datasource-project-services") %>>
|
||||||
<a href="/docs/providers/google/d/google_project_services.html">google_project_services</a>
|
<a href="/docs/providers/google/d/google_project_services.html">google_project_services</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li<%= sidebar_current("docs-google-datasource-compute-node-types") %>>
|
||||||
|
<a href="/docs/providers/google/d/google_compute_node_types.html">google_compute_node_types</a>
|
||||||
|
</li>
|
||||||
<li<%= sidebar_current("docs-google-datasource-compute-regions") %>>
|
<li<%= sidebar_current("docs-google-datasource-compute-regions") %>>
|
||||||
<a href="/docs/providers/google/d/google_compute_regions.html">google_compute_regions</a>
|
<a href="/docs/providers/google/d/google_compute_regions.html">google_compute_regions</a>
|
||||||
</li>
|
</li>
|
||||||
@ -407,6 +410,10 @@
|
|||||||
<a href="/docs/providers/google/r/compute_interconnect_attachment.html">google_compute_interconnect_attachment</a>
|
<a href="/docs/providers/google/r/compute_interconnect_attachment.html">google_compute_interconnect_attachment</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li<%= sidebar_current("docs-google-compute-node-template") %>>
|
||||||
|
<a href="/docs/providers/google/r/compute_node_template.html">google_compute_node_template</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li<%= sidebar_current("docs-google-compute-network-x") %>>
|
<li<%= sidebar_current("docs-google-compute-network-x") %>>
|
||||||
<a href="/docs/providers/google/r/compute_network.html">google_compute_network</a>
|
<a href="/docs/providers/google/r/compute_network.html">google_compute_network</a>
|
||||||
</li>
|
</li>
|
||||||
|
Loading…
Reference in New Issue
Block a user