Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add max_run_duration to instance and instance template on Beta #6812

Merged
merged 19 commits into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ var (
"scheduling.0.min_node_cpus",
"scheduling.0.provisioning_model",
"scheduling.0.instance_termination_action",
<% unless version == 'ga' -%>
"scheduling.0.max_run_duration",
<% end -%>

}

shieldedInstanceConfigKeys = []string{
Expand Down Expand Up @@ -643,6 +647,33 @@ func resourceComputeInstance() *schema.Resource {
AtLeastOneOf: schedulingKeys,
Description: `Specifies the action GCE should take when SPOT VM is preempted.`,
},
<% unless version == 'ga' -%>
"max_run_duration" : {
andrewyz marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeList,
Optional: true,
Description: `The timeout for new network connections to hosts.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"seconds": {
Type: schema.TypeInt,
Required: true,
Description: `Span of time at a resolution of a second.
Must be from 0 to 315,576,000,000 inclusive.`,
},
"nanos": {
Type: schema.TypeInt,
Optional: true,
Description: `Span of time that's a fraction of a second at nanosecond
resolution. Durations less than one second are represented
with a 0 seconds field and a positive nanos field. Must
be from 0 to 999,999,999 inclusive.`,
},
},
},
},
<% end -%>

},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ var (
"scheduling.0.node_affinities",
"scheduling.0.min_node_cpus",
"scheduling.0.provisioning_model",
"scheduling.0.instance_termination_action",
"scheduling.0.instance_termination_action",
<% unless version == 'ga' -%>
"scheduling.0.max_run_duration",
<% end -%>
}

shieldedInstanceTemplateConfigKeys = []string{
Expand Down Expand Up @@ -553,6 +556,32 @@ func resourceComputeInstanceTemplate() *schema.Resource {
AtLeastOneOf: schedulingInstTemplateKeys,
Description: `Specifies the action GCE should take when SPOT VM is preempted.`,
},
<% unless version == 'ga' -%>
"max_run_duration" : {
Type: schema.TypeList,
Optional: true,
Description: `The timeout for new network connections to hosts.`,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"seconds": {
Type: schema.TypeInt,
Required: true,
Description: `Span of time at a resolution of a second.
Must be from 0 to 315,576,000,000 inclusive.`,
},
"nanos": {
Type: schema.TypeInt,
Optional: true,
Description: `Span of time that's a fraction of a second at nanosecond
resolution. Durations less than one second are represented
with a 0 seconds field and a positive nanos field. Must
be from 0 to 999,999,999 inclusive.`,
},
},
},
},
<% end -%>
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1102,14 +1102,20 @@ func TestAccComputeInstanceTemplate_managedEnvoy(t *testing.T) {
ImportState: true,
ImportStateVerify: true,
},
},
},
})
}

func TestAccComputeInstanceTemplate_spot(t *testing.T) {
t.Parallel()

var instanceTemplate compute.InstanceTemplate
<% unless version == 'ga' -%>
var expectedMaxRunDuration = compute.Duration{}
// Define in testAccComputeInstanceTemplate_spot
expectedMaxRunDuration.Nanos = 123
expectedMaxRunDuration.Seconds = 60
<% end -%>

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -1125,6 +1131,9 @@ func TestAccComputeInstanceTemplate_spot(t *testing.T) {
testAccCheckComputeInstanceTemplatePreemptible(&instanceTemplate, true),
testAccCheckComputeInstanceTemplateProvisioningModel(&instanceTemplate, "SPOT"),
testAccCheckComputeInstanceTemplateInstanceTerminationAction(&instanceTemplate, "STOP"),
<% unless version == 'ga' -%>
testAccCheckComputeInstanceTemplateMaxRunDuration(&instanceTemplate, expectedMaxRunDuration),
<% end -%>
),
},
{
Expand Down Expand Up @@ -1302,6 +1311,20 @@ func testAccCheckComputeInstanceTemplateInstanceTerminationAction(instanceTempla
}


<% unless version == 'ga' -%>
func testAccCheckComputeInstanceTemplateMaxRunDuration(instanceTemplate *compute.InstanceTemplate, instance_max_run_duration_want compute.Duration) resource.TestCheckFunc {
return func(s *terraform.State) error {
if !reflect.DeepEqual(*instanceTemplate.Properties.Scheduling.MaxRunDuration, instance_max_run_duration_want) {
return fmt.Errorf("gExpected instance_termination_action: %#v; got %#v", instance_max_run_duration_want, instanceTemplate.Properties.Scheduling.MaxRunDuration)
}

return nil
}
}
<% end -%>



func testAccCheckComputeInstanceTemplateAutomaticRestart(instanceTemplate *compute.InstanceTemplate, automaticRestart bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
ar := instanceTemplate.Properties.Scheduling.AutomaticRestart
Expand Down Expand Up @@ -2874,6 +2897,13 @@ resource "google_compute_instance_template" "foobar" {
automatic_restart = false
provisioning_model = "SPOT"
instance_termination_action = "STOP"
<% unless version == 'ga' -%>
max_run_duration {
nanos = 123
seconds = 60
}
andrewyz marked this conversation as resolved.
Show resolved Hide resolved
<% end -%>

}

metadata = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import (
"context"
"fmt"
"log"
<% if version == "ga" -%>
<% else -%>
andrewyz marked this conversation as resolved.
Show resolved Hide resolved
"reflect"
<% end -%>
"regexp"
"sort"
"strconv"
Expand Down Expand Up @@ -2236,6 +2240,12 @@ func TestAccComputeInstance_spotVM(t *testing.T) {

var instance compute.Instance
var instanceName = fmt.Sprintf("tf-test-%s", randString(t, 10))
<% unless version == 'ga' -%>
var expectedMaxRunDuration = compute.Duration{}
// Define in testAccComputeInstance_spotVM
expectedMaxRunDuration.Nanos = 123
expectedMaxRunDuration.Seconds = 60
<% end -%>

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -2248,6 +2258,9 @@ func TestAccComputeInstance_spotVM(t *testing.T) {
testAccCheckComputeInstanceExists(
t, "google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceTerminationAction(&instance, "STOP"),
<% unless version == 'ga' -%>
testAccCheckComputeInstanceMaxRunDuration(&instance, expectedMaxRunDuration),
<% end -%>
),
},
computeInstanceImportStep("us-central1-a", instanceName, []string{}),
Expand All @@ -2260,7 +2273,12 @@ func TestAccComputeInstance_spotVM_update(t *testing.T) {

var instance compute.Instance
var instanceName = fmt.Sprintf("tf-test-%s", randString(t, 10))

<% unless version == 'ga' -%>
// Define in testAccComputeInstance_spotVM
var expectedMaxRunDuration = compute.Duration{}
expectedMaxRunDuration.Nanos = 123
expectedMaxRunDuration.Seconds = 60
<% end -%>
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Expand All @@ -2279,6 +2297,11 @@ func TestAccComputeInstance_spotVM_update(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
t, "google_compute_instance.foobar", &instance),
<% unless version == 'ga' -%>
testAccCheckComputeInstanceMaxRunDuration(&instance, expectedMaxRunDuration),
andrewyz marked this conversation as resolved.
Show resolved Hide resolved
<% end -%>


),
},
computeInstanceImportStep("us-central1-a", instanceName, []string{}),
Expand Down Expand Up @@ -2603,6 +2626,26 @@ func testAccCheckComputeResourcePolicy(instance *compute.Instance, scheduleName
}
}

<% unless version == 'ga' -%>
func testAccCheckComputeInstanceMaxRunDuration(instance *compute.Instance, instanceMaxRunDurationWant compute.Duration) resource.TestCheckFunc {
return func(s *terraform.State) error {
if instance == nil {
return fmt.Errorf("instance is nil")
}
if instance.Scheduling == nil {
return fmt.Errorf("no scheduling")
}

if !reflect.DeepEqual(*instance.Scheduling.MaxRunDuration, instanceMaxRunDurationWant) {
return fmt.Errorf("got the wrong instance max run duration action: have: %#v; want: %#v",instance.Scheduling.MaxRunDuration, instanceMaxRunDurationWant)
}

return nil
}
}
<% end -%>


func testAccCheckComputeInstanceTerminationAction(instance *compute.Instance, instanceTerminationActionWant string) resource.TestCheckFunc {
return func(s *terraform.State) error {
if instance == nil {
Expand Down Expand Up @@ -6315,8 +6358,13 @@ resource "google_compute_instance" "foobar" {
automatic_restart = false
preemptible = true
instance_termination_action = "STOP"
<% unless version == 'ga' -%>
max_run_duration {
nanos = 123
seconds = 60
}
<% end -%>
}

}
`, instance)
}
Expand Down
65 changes: 65 additions & 0 deletions mmv1/third_party/terraform/utils/compute_instance_helpers.go.erb
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,56 @@ func expandScheduling(v interface{}) (*compute.Scheduling, error) {
scheduling.InstanceTerminationAction = v.(string)
scheduling.ForceSendFields = append(scheduling.ForceSendFields, "InstanceTerminationAction")
}
<% unless version == 'ga' -%>
if v, ok := original["max_run_duration"]; ok {
transformedMaxRunDuration, err := expandComputeMaxRunDuration(v)
if err != nil {
return nil, err
}
scheduling.MaxRunDuration = transformedMaxRunDuration
scheduling.ForceSendFields = append(scheduling.ForceSendFields, "MaxRunDuration")
andrewyz marked this conversation as resolved.
Show resolved Hide resolved
}
<% end -%>
return scheduling, nil
}

<% unless version == 'ga' -%>
func expandComputeMaxRunDuration(v interface{}) (*compute.Duration, error) {
l := v.([]interface{})
duration := compute.Duration{}
if len(l) == 0 || l[0] == nil {
return nil, nil
}
raw := l[0]
original := raw.(map[string]interface{})

transformedNanos, err := expandComputeMaxRunDurationNanos(original["nanos"])
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedNanos); val.IsValid() && !isEmptyValue(val) {
duration.Nanos = int64(transformedNanos.(int))
}

transformedSeconds, err := expandComputeMaxRunDurationSeconds(original["seconds"])
if err != nil {
return nil, err
} else if val := reflect.ValueOf(transformedSeconds); val.IsValid() && !isEmptyValue(val) {
duration.Seconds = int64(transformedSeconds.(int))
}

return &duration, nil
}

func expandComputeMaxRunDurationNanos(v interface{}) (interface{}, error) {
return v, nil
}

func expandComputeMaxRunDurationSeconds(v interface{}) (interface{}, error) {
return v, nil
}
<% end -%>


func flattenScheduling(resp *compute.Scheduling) []map[string]interface{} {
schedulingMap := map[string]interface{}{
"on_host_maintenance": resp.OnHostMaintenance,
Expand All @@ -146,6 +193,12 @@ func flattenScheduling(resp *compute.Scheduling) []map[string]interface{} {
schedulingMap["automatic_restart"] = *resp.AutomaticRestart
}

<% unless version == 'ga' -%>
if resp.MaxRunDuration != nil {
schedulingMap["max_run_duration"] = flattenComputeMaxRunDuration(resp.MaxRunDuration)
}
<% end -%>

nodeAffinities := schema.NewSet(schema.HashResource(instanceSchedulingNodeAffinitiesElemSchema()), nil)
for _, na := range resp.NodeAffinities {
nodeAffinities.Add(map[string]interface{}{
Expand All @@ -159,6 +212,18 @@ func flattenScheduling(resp *compute.Scheduling) []map[string]interface{} {
return []map[string]interface{}{schedulingMap}
}

<% unless version == 'ga' -%>
func flattenComputeMaxRunDuration(v *compute.Duration) []interface{} {
if v == nil {
return nil
}
transformed := make(map[string]interface{})
transformed["nanos"] = v.Nanos
transformed["seconds"] = v.Seconds
return []interface{}{transformed}
}
<% end -%>

func flattenAccessConfigs(accessConfigs []*compute.AccessConfig) ([]map[string]interface{}, string) {
flattened := make([]map[string]interface{}, len(accessConfigs))
natIP := ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,9 @@ specified, then this instance will have no external IPv6 Internet access. Struct

* `instance_termination_action` - (Optional) Describe the type of termination action for `SPOT` VM. Can be `STOP` or `DELETE`. Read more on [here](https://cloud.google.com/compute/docs/instances/create-use-spot)

* `max_run_duration` - (Optional) [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html) The duration this instance will run and be terminated after then. Accept 'nanos' and 'secoonds', or both.
andrewyz marked this conversation as resolved.
Show resolved Hide resolved


<a name="nested_guest_accelerator"></a>The `guest_accelerator` block supports:

* `type` (Required) - The accelerator type resource to expose to this instance. E.g. `nvidia-tesla-k80`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,9 @@ specified, then this instance will have no external IPv6 Internet access. Struct
`SPOT`, read [here](https://cloud.google.com/compute/docs/instances/spot)

* `instance_termination_action` - (Optional) Describe the type of termination action for `SPOT` VM. Can be `STOP` or `DELETE`. Read more on [here](https://cloud.google.com/compute/docs/instances/create-use-spot)

* `max_run_duration` - (Optional) [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html) The duration this instance will run and be terminated after then


<a name="nested_guest_accelerator"></a>The `guest_accelerator` block supports:

Expand Down