2015-02-16 16:06:23 +00:00
package google
import (
"fmt"
"log"
2015-10-23 19:06:46 +00:00
"strings"
2016-08-05 18:30:41 +00:00
"time"
2015-02-16 16:06:23 +00:00
2018-03-20 21:20:43 +00:00
"github.com/hashicorp/terraform/helper/resource"
2015-02-16 16:06:23 +00:00
"github.com/hashicorp/terraform/helper/schema"
2017-08-02 17:12:16 +00:00
"github.com/hashicorp/terraform/helper/validation"
2018-10-24 22:04:58 +00:00
2017-07-26 20:37:59 +00:00
computeBeta "google.golang.org/api/compute/v0.beta"
2016-08-05 18:30:41 +00:00
"google.golang.org/api/compute/v1"
2015-02-16 16:06:23 +00:00
)
2015-07-28 00:47:10 +00:00
func resourceComputeInstanceGroupManager ( ) * schema . Resource {
2015-02-16 16:06:23 +00:00
return & schema . Resource {
2015-07-28 00:47:10 +00:00
Create : resourceComputeInstanceGroupManagerCreate ,
Read : resourceComputeInstanceGroupManagerRead ,
Update : resourceComputeInstanceGroupManagerUpdate ,
Delete : resourceComputeInstanceGroupManagerDelete ,
2016-08-05 18:30:41 +00:00
Importer : & schema . ResourceImporter {
2018-03-21 19:39:12 +00:00
State : resourceInstanceGroupManagerStateImporter ,
2016-08-05 18:30:41 +00:00
} ,
2015-02-16 16:06:23 +00:00
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"base_instance_name" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeString ,
Required : true ,
ForceNew : true ,
} ,
2018-12-14 20:51:11 +00:00
"instance_template" : {
2017-07-26 20:37:59 +00:00
Type : schema . TypeString ,
2019-02-15 22:25:03 +00:00
Required : true ,
2017-07-26 20:37:59 +00:00
DiffSuppressFunc : compareSelfLinkRelativePaths ,
2016-04-10 21:34:15 +00:00
} ,
2018-12-14 20:51:11 +00:00
"version" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeList ,
Optional : true ,
Computed : true ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"name" : {
2018-06-04 22:34:48 +00:00
Type : schema . TypeString ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
} ,
2018-12-14 20:51:11 +00:00
"instance_template" : {
2018-06-04 22:34:48 +00:00
Type : schema . TypeString ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
DiffSuppressFunc : compareSelfLinkRelativePaths ,
} ,
2018-12-14 20:51:11 +00:00
"target_size" : {
2018-06-04 22:34:48 +00:00
Type : schema . TypeList ,
Optional : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
MaxItems : 1 ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"fixed" : {
2018-06-04 22:34:48 +00:00
Type : schema . TypeInt ,
Optional : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
} ,
2018-12-14 20:51:11 +00:00
"percent" : {
2018-06-04 22:34:48 +00:00
Type : schema . TypeInt ,
Optional : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-06-04 22:34:48 +00:00
ValidateFunc : validation . IntBetween ( 0 , 100 ) ,
} ,
} ,
} ,
} ,
} ,
} ,
} ,
2018-12-14 20:51:11 +00:00
"name" : {
2016-04-10 21:34:15 +00:00
Type : schema . TypeString ,
Required : true ,
2015-02-16 16:06:23 +00:00
ForceNew : true ,
} ,
2018-12-14 20:51:11 +00:00
"zone" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeString ,
2017-12-06 22:30:04 +00:00
Optional : true ,
2018-01-03 21:18:40 +00:00
Computed : true ,
2015-02-16 16:06:23 +00:00
ForceNew : true ,
} ,
2018-12-14 20:51:11 +00:00
"description" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeString ,
2016-04-10 21:34:15 +00:00
Optional : true ,
ForceNew : true ,
2015-02-16 16:06:23 +00:00
} ,
2018-12-14 20:51:11 +00:00
"fingerprint" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeString ,
Computed : true ,
} ,
2018-12-14 20:51:11 +00:00
"instance_group" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeString ,
2016-04-10 21:34:15 +00:00
Computed : true ,
2015-02-16 16:06:23 +00:00
} ,
2018-12-14 20:51:11 +00:00
"named_port" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeSet ,
2016-01-10 14:09:05 +00:00
Optional : true ,
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"name" : {
2016-01-10 14:09:05 +00:00
Type : schema . TypeString ,
Required : true ,
} ,
2018-12-14 20:51:11 +00:00
"port" : {
2016-01-10 14:09:05 +00:00
Type : schema . TypeInt ,
Required : true ,
} ,
} ,
} ,
} ,
2018-12-14 20:51:11 +00:00
"project" : {
2016-04-10 21:34:15 +00:00
Type : schema . TypeString ,
Optional : true ,
ForceNew : true ,
2016-08-05 18:30:41 +00:00
Computed : true ,
2016-04-10 21:34:15 +00:00
} ,
2018-12-14 20:51:11 +00:00
"self_link" : {
2016-04-10 21:34:15 +00:00
Type : schema . TypeString ,
Computed : true ,
} ,
2018-12-14 20:51:11 +00:00
"update_strategy" : {
2017-09-14 00:06:07 +00:00
Type : schema . TypeString ,
Optional : true ,
2018-10-03 00:22:42 +00:00
Default : "REPLACE" ,
ValidateFunc : validation . StringInSlice ( [ ] string { "RESTART" , "NONE" , "ROLLING_UPDATE" , "REPLACE" } , false ) ,
DiffSuppressFunc : func ( key , old , new string , d * schema . ResourceData ) bool {
if old == "REPLACE" && new == "RESTART" {
return true
}
if old == "RESTART" && new == "REPLACE" {
return true
}
return false
} ,
2015-11-12 20:44:31 +00:00
} ,
2018-12-14 20:51:11 +00:00
"target_pools" : {
2017-09-14 00:06:07 +00:00
Type : schema . TypeSet ,
Optional : true ,
2017-07-26 20:37:59 +00:00
Elem : & schema . Schema {
Type : schema . TypeString ,
} ,
Set : selfLinkRelativePathHash ,
2015-02-16 16:06:23 +00:00
} ,
2018-12-14 20:51:11 +00:00
"target_size" : {
2015-02-16 16:06:23 +00:00
Type : schema . TypeInt ,
Computed : true ,
2015-05-17 00:14:38 +00:00
Optional : true ,
2015-02-16 16:06:23 +00:00
} ,
2017-08-02 17:12:16 +00:00
2018-12-14 20:51:11 +00:00
"auto_healing_policies" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeList ,
Optional : true ,
MaxItems : 1 ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2017-08-02 17:12:16 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"health_check" : {
2017-08-02 17:12:16 +00:00
Type : schema . TypeString ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2017-08-02 17:12:16 +00:00
DiffSuppressFunc : compareSelfLinkRelativePaths ,
} ,
2018-12-14 20:51:11 +00:00
"initial_delay_sec" : {
2017-08-02 17:12:16 +00:00
Type : schema . TypeInt ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2017-08-02 17:12:16 +00:00
ValidateFunc : validation . IntBetween ( 0 , 3600 ) ,
} ,
} ,
} ,
} ,
2018-06-04 22:34:48 +00:00
2018-12-14 20:51:11 +00:00
"rolling_update_policy" : {
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
Computed : true ,
Type : schema . TypeList ,
Optional : true ,
MaxItems : 1 ,
2018-03-15 18:10:09 +00:00
Elem : & schema . Resource {
Schema : map [ string ] * schema . Schema {
2018-12-14 20:51:11 +00:00
"minimal_action" : {
2018-03-15 18:10:09 +00:00
Type : schema . TypeString ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-03-15 18:10:09 +00:00
ValidateFunc : validation . StringInSlice ( [ ] string { "RESTART" , "REPLACE" } , false ) ,
} ,
2018-12-14 20:51:11 +00:00
"type" : {
2018-03-15 18:10:09 +00:00
Type : schema . TypeString ,
Required : true ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-03-15 18:10:09 +00:00
ValidateFunc : validation . StringInSlice ( [ ] string { "OPPORTUNISTIC" , "PROACTIVE" } , false ) ,
} ,
2018-12-14 20:51:11 +00:00
"max_surge_fixed" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeInt ,
Optional : true ,
Computed : true ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-03-15 18:10:09 +00:00
} ,
2018-12-14 20:51:11 +00:00
"max_surge_percent" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeInt ,
Optional : true ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
ValidateFunc : validation . IntBetween ( 0 , 100 ) ,
2018-03-15 18:10:09 +00:00
} ,
2018-12-14 20:51:11 +00:00
"max_unavailable_fixed" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeInt ,
Optional : true ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-03-15 18:10:09 +00:00
} ,
2018-12-14 20:51:11 +00:00
"max_unavailable_percent" : {
2018-11-20 23:35:04 +00:00
Type : schema . TypeInt ,
Optional : true ,
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
ValidateFunc : validation . IntBetween ( 0 , 100 ) ,
2018-03-15 18:10:09 +00:00
} ,
2018-12-14 20:51:11 +00:00
"min_ready_sec" : {
2018-03-15 18:10:09 +00:00
Type : schema . TypeInt ,
2018-11-20 23:35:04 +00:00
Removed : "This field is in beta. Use it in the the google-beta provider instead. See https://terraform.io/docs/providers/google/provider_versions.html for more details." ,
2018-03-15 18:10:09 +00:00
Optional : true ,
ValidateFunc : validation . IntBetween ( 0 , 3600 ) ,
} ,
} ,
} ,
} ,
2018-06-04 22:34:48 +00:00
2018-12-14 20:51:11 +00:00
"wait_for_instances" : {
2018-03-20 21:20:43 +00:00
Type : schema . TypeBool ,
Optional : true ,
2018-03-21 19:39:12 +00:00
Default : false ,
2018-03-20 21:20:43 +00:00
} ,
2015-02-16 16:06:23 +00:00
} ,
}
}
2016-01-10 14:09:05 +00:00
func getNamedPorts ( nps [ ] interface { } ) [ ] * compute . NamedPort {
namedPorts := make ( [ ] * compute . NamedPort , 0 , len ( nps ) )
for _ , v := range nps {
np := v . ( map [ string ] interface { } )
namedPorts = append ( namedPorts , & compute . NamedPort {
Name : np [ "name" ] . ( string ) ,
Port : int64 ( np [ "port" ] . ( int ) ) ,
} )
}
2017-07-26 20:37:59 +00:00
return namedPorts
}
func getNamedPortsBeta ( nps [ ] interface { } ) [ ] * computeBeta . NamedPort {
namedPorts := make ( [ ] * computeBeta . NamedPort , 0 , len ( nps ) )
for _ , v := range nps {
np := v . ( map [ string ] interface { } )
namedPorts = append ( namedPorts , & computeBeta . NamedPort {
Name : np [ "name" ] . ( string ) ,
Port : int64 ( np [ "port" ] . ( int ) ) ,
} )
}
2016-01-10 14:09:05 +00:00
return namedPorts
}
2015-07-28 00:47:10 +00:00
func resourceComputeInstanceGroupManagerCreate ( d * schema . ResourceData , meta interface { } ) error {
2015-02-16 16:06:23 +00:00
config := meta . ( * Config )
2016-04-10 16:59:57 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
}
2017-12-06 22:30:04 +00:00
zone , err := getZone ( d , config )
if err != nil {
return err
}
2015-02-16 16:06:23 +00:00
// Build the parameter
2017-07-26 20:37:59 +00:00
manager := & computeBeta . InstanceGroupManager {
2018-11-20 23:35:04 +00:00
Name : d . Get ( "name" ) . ( string ) ,
Description : d . Get ( "description" ) . ( string ) ,
BaseInstanceName : d . Get ( "base_instance_name" ) . ( string ) ,
InstanceTemplate : d . Get ( "instance_template" ) . ( string ) ,
TargetSize : int64 ( d . Get ( "target_size" ) . ( int ) ) ,
NamedPorts : getNamedPortsBeta ( d . Get ( "named_port" ) . ( * schema . Set ) . List ( ) ) ,
TargetPools : convertStringSet ( d . Get ( "target_pools" ) . ( * schema . Set ) ) ,
2017-06-16 22:39:44 +00:00
// Force send TargetSize to allow a value of 0.
2017-06-16 22:41:26 +00:00
ForceSendFields : [ ] string { "TargetSize" } ,
2015-02-16 16:06:23 +00:00
}
log . Printf ( "[DEBUG] InstanceGroupManager insert request: %#v" , manager )
2018-05-09 18:24:40 +00:00
op , err := config . clientComputeBeta . InstanceGroupManagers . Insert (
project , zone , manager ) . Do ( )
2017-07-26 20:37:59 +00:00
2015-02-16 16:06:23 +00:00
if err != nil {
return fmt . Errorf ( "Error creating InstanceGroupManager: %s" , err )
}
// It probably maybe worked, so store the ID now
2019-01-28 22:00:05 +00:00
id , err := replaceVars ( d , config , "{{project}}/{{zone}}/{{name}}" )
if err != nil {
return err
}
d . SetId ( id )
2015-02-16 16:06:23 +00:00
// Wait for the operation to complete
2017-10-13 22:36:03 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Creating InstanceGroupManager" )
2015-02-16 16:06:23 +00:00
if err != nil {
return err
}
2015-07-28 00:47:10 +00:00
return resourceComputeInstanceGroupManagerRead ( d , meta )
2015-02-16 16:06:23 +00:00
}
2017-07-26 20:37:59 +00:00
func flattenNamedPortsBeta ( namedPorts [ ] * computeBeta . NamedPort ) [ ] map [ string ] interface { } {
2016-08-05 18:30:41 +00:00
result := make ( [ ] map [ string ] interface { } , 0 , len ( namedPorts ) )
for _ , namedPort := range namedPorts {
namedPortMap := make ( map [ string ] interface { } )
namedPortMap [ "name" ] = namedPort . Name
namedPortMap [ "port" ] = namedPort . Port
result = append ( result , namedPortMap )
}
return result
}
2018-03-20 21:20:43 +00:00
func getManager ( d * schema . ResourceData , meta interface { } ) ( * computeBeta . InstanceGroupManager , error ) {
2015-02-16 16:06:23 +00:00
config := meta . ( * Config )
2019-01-28 22:00:05 +00:00
if err := parseImportId ( [ ] string { "(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<name>[^/]+)" , "(?P<project>[^/]+)/(?P<name>[^/]+)" , "(?P<name>[^/]+)" } , d , config ) ; err != nil {
2018-03-20 21:20:43 +00:00
return nil , err
2016-04-10 16:59:57 +00:00
}
2018-12-17 20:57:26 +00:00
2019-01-28 22:00:05 +00:00
project , err := getProject ( d , config )
if err != nil {
return nil , err
2018-10-16 23:53:48 +00:00
}
2018-12-17 20:57:26 +00:00
2019-01-28 22:00:05 +00:00
zone , _ := getZone ( d , config )
name := d . Get ( "name" ) . ( string )
2015-02-16 16:06:23 +00:00
2019-01-28 22:00:05 +00:00
manager , err := config . clientComputeBeta . InstanceGroupManagers . Get ( project , zone , name ) . Do ( )
2018-12-17 20:57:26 +00:00
if err != nil {
2019-01-28 22:00:05 +00:00
return nil , handleNotFoundError ( err , d , fmt . Sprintf ( "Instance Group Manager %q" , name ) )
2018-05-09 18:24:40 +00:00
}
2018-05-03 19:24:21 +00:00
2018-05-09 18:24:40 +00:00
if manager == nil {
log . Printf ( "[WARN] Removing Instance Group Manager %q because it's gone" , d . Get ( "name" ) . ( string ) )
2018-05-04 14:51:45 +00:00
2018-05-09 18:24:40 +00:00
// The resource doesn't exist anymore
d . SetId ( "" )
return nil , nil
2018-05-04 14:51:45 +00:00
}
2018-05-09 18:24:40 +00:00
2018-03-20 21:20:43 +00:00
return manager , nil
}
func resourceComputeInstanceGroupManagerRead ( d * schema . ResourceData , meta interface { } ) error {
config := meta . ( * Config )
project , err := getProject ( d , config )
if err != nil {
return err
}
manager , err := getManager ( d , meta )
2018-10-19 16:36:14 +00:00
if err != nil {
2018-03-20 21:20:43 +00:00
return err
}
2018-10-19 16:36:14 +00:00
if manager == nil {
log . Printf ( "[WARN] Instance Group Manager %q not found, removing from state." , d . Id ( ) )
d . SetId ( "" )
return nil
}
2016-08-05 18:30:41 +00:00
d . Set ( "base_instance_name" , manager . BaseInstanceName )
2018-05-09 18:24:40 +00:00
d . Set ( "instance_template" , ConvertSelfLinkToV1 ( manager . InstanceTemplate ) )
2016-08-05 18:30:41 +00:00
d . Set ( "name" , manager . Name )
2017-09-14 00:06:07 +00:00
d . Set ( "zone" , GetResourceNameFromSelfLink ( manager . Zone ) )
2016-08-05 18:30:41 +00:00
d . Set ( "description" , manager . Description )
d . Set ( "project" , project )
d . Set ( "target_size" , manager . TargetSize )
2019-03-15 23:34:30 +00:00
if err = d . Set ( "target_pools" , mapStringArr ( manager . TargetPools , ConvertSelfLinkToV1 ) ) ; err != nil {
2018-10-19 16:36:14 +00:00
return fmt . Errorf ( "Error setting target_pools in state: %s" , err . Error ( ) )
}
if err = d . Set ( "named_port" , flattenNamedPortsBeta ( manager . NamedPorts ) ) ; err != nil {
return fmt . Errorf ( "Error setting named_port in state: %s" , err . Error ( ) )
}
2015-02-16 16:06:23 +00:00
d . Set ( "fingerprint" , manager . Fingerprint )
2018-05-09 18:24:40 +00:00
d . Set ( "instance_group" , ConvertSelfLinkToV1 ( manager . InstanceGroup ) )
2017-07-26 20:37:59 +00:00
d . Set ( "self_link" , ConvertSelfLinkToV1 ( manager . SelfLink ) )
2018-10-19 16:36:14 +00:00
2017-01-09 23:15:50 +00:00
update_strategy , ok := d . GetOk ( "update_strategy" )
if ! ok {
2018-10-03 00:22:42 +00:00
update_strategy = "REPLACE"
2017-01-09 23:15:50 +00:00
}
d . Set ( "update_strategy" , update_strategy . ( string ) )
2018-11-20 23:35:04 +00:00
// When we make a list Removed, we see a permadiff from `field_name.#: "" => "<computed>"`. Set to nil in Read so we see no diff.
d . Set ( "version" , nil )
d . Set ( "rolling_update_policy" , nil )
2015-02-16 16:06:23 +00:00
2018-03-20 21:20:43 +00:00
if d . Get ( "wait_for_instances" ) . ( bool ) {
conf := resource . StateChangeConf {
Pending : [ ] string { "creating" , "error" } ,
Target : [ ] string { "created" } ,
Refresh : waitForInstancesRefreshFunc ( getManager , d , meta ) ,
Timeout : d . Timeout ( schema . TimeoutCreate ) ,
}
_ , err := conf . WaitForState ( )
if err != nil {
return err
}
}
2015-02-16 16:06:23 +00:00
return nil
}
2017-07-26 20:37:59 +00:00
2018-07-25 20:21:20 +00:00
// Updates an instance group manager by applying the update strategy (REPLACE, RESTART)
// and rolling update policy (PROACTIVE, OPPORTUNISTIC). Updates performed by API
// are OPPORTUNISTIC by default.
2018-11-20 23:35:04 +00:00
func performZoneUpdate ( config * Config , id string , updateStrategy string , project string , zone string ) error {
2018-10-03 00:22:42 +00:00
if updateStrategy == "RESTART" || updateStrategy == "REPLACE" {
2018-06-04 22:34:48 +00:00
managedInstances , err := config . clientComputeBeta . InstanceGroupManagers . ListManagedInstances ( project , zone , id ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error getting instance group managers instances: %s" , err )
}
managedInstanceCount := len ( managedInstances . ManagedInstances )
instances := make ( [ ] string , managedInstanceCount )
for i , v := range managedInstances . ManagedInstances {
instances [ i ] = v . Instance
}
recreateInstances := & computeBeta . InstanceGroupManagersRecreateInstancesRequest {
Instances : instances ,
}
op , err := config . clientComputeBeta . InstanceGroupManagers . RecreateInstances ( project , zone , id , recreateInstances ) . Do ( )
if err != nil {
return fmt . Errorf ( "Error restarting instance group managers instances: %s" , err )
}
// Wait for the operation to complete
err = computeSharedOperationWaitTime ( config . clientCompute , op , project , managedInstanceCount * 4 , "Restarting InstanceGroupManagers instances" )
if err != nil {
return err
}
}
return nil
}
2015-07-28 00:47:10 +00:00
func resourceComputeInstanceGroupManagerUpdate ( d * schema . ResourceData , meta interface { } ) error {
2015-02-16 16:06:23 +00:00
config := meta . ( * Config )
2019-01-28 22:00:05 +00:00
if err := parseImportId ( [ ] string { "(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<name>[^/]+)" , "(?P<project>[^/]+)/(?P<name>[^/]+)" , "(?P<name>[^/]+)" } , d , config ) ; err != nil {
2016-04-10 16:59:57 +00:00
return err
}
2019-01-28 22:00:05 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
2017-12-06 22:30:04 +00:00
}
2019-01-28 22:00:05 +00:00
zone , _ := getZone ( d , config )
name := d . Get ( "name" ) . ( string )
2015-02-16 16:06:23 +00:00
d . Partial ( true )
// If target_pools changes then update
if d . HasChange ( "target_pools" ) {
2017-09-14 00:06:07 +00:00
targetPools := convertStringSet ( d . Get ( "target_pools" ) . ( * schema . Set ) )
2015-02-16 16:06:23 +00:00
// Build the parameter
2017-07-26 20:37:59 +00:00
setTargetPools := & computeBeta . InstanceGroupManagersSetTargetPoolsRequest {
2015-02-16 16:06:23 +00:00
Fingerprint : d . Get ( "fingerprint" ) . ( string ) ,
TargetPools : targetPools ,
}
2018-05-09 18:24:40 +00:00
op , err := config . clientComputeBeta . InstanceGroupManagers . SetTargetPools (
2019-01-28 22:00:05 +00:00
project , zone , name , setTargetPools ) . Do ( )
2017-07-26 20:37:59 +00:00
2015-02-16 16:06:23 +00:00
if err != nil {
return fmt . Errorf ( "Error updating InstanceGroupManager: %s" , err )
}
// Wait for the operation to complete
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Updating InstanceGroupManager" )
2015-02-16 16:06:23 +00:00
if err != nil {
return err
}
d . SetPartial ( "target_pools" )
}
2016-01-10 14:09:05 +00:00
// If named_port changes then update:
if d . HasChange ( "named_port" ) {
// Build the parameters for a "SetNamedPorts" request:
2018-11-20 23:35:04 +00:00
namedPorts := getNamedPortsBeta ( d . Get ( "named_port" ) . ( * schema . Set ) . List ( ) )
2017-07-26 20:37:59 +00:00
setNamedPorts := & computeBeta . InstanceGroupsSetNamedPortsRequest {
2016-01-10 14:09:05 +00:00
NamedPorts : namedPorts ,
}
// Make the request:
2018-05-09 18:24:40 +00:00
op , err := config . clientComputeBeta . InstanceGroups . SetNamedPorts (
2019-01-28 22:00:05 +00:00
project , zone , name , setNamedPorts ) . Do ( )
2017-07-26 20:37:59 +00:00
2016-01-10 14:09:05 +00:00
if err != nil {
return fmt . Errorf ( "Error updating InstanceGroupManager: %s" , err )
}
// Wait for the operation to complete:
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Updating InstanceGroupManager" )
2016-01-10 14:09:05 +00:00
if err != nil {
return err
}
d . SetPartial ( "named_port" )
}
2015-05-17 00:14:38 +00:00
if d . HasChange ( "target_size" ) {
2017-06-16 22:39:44 +00:00
targetSize := int64 ( d . Get ( "target_size" ) . ( int ) )
2018-05-09 18:24:40 +00:00
op , err := config . clientComputeBeta . InstanceGroupManagers . Resize (
2019-01-28 22:00:05 +00:00
project , zone , name , targetSize ) . Do ( )
2017-07-26 20:37:59 +00:00
2017-06-13 19:43:18 +00:00
if err != nil {
return fmt . Errorf ( "Error updating InstanceGroupManager: %s" , err )
}
2015-02-16 16:06:23 +00:00
2017-06-13 19:43:18 +00:00
// Wait for the operation to complete
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Updating InstanceGroupManager" )
2017-06-13 19:43:18 +00:00
if err != nil {
return err
2015-02-16 16:06:23 +00:00
}
2015-05-17 00:14:38 +00:00
d . SetPartial ( "target_size" )
2015-02-16 16:06:23 +00:00
}
2018-06-04 22:34:48 +00:00
// If instance_template changes then update
if d . HasChange ( "instance_template" ) {
// Build the parameter
setInstanceTemplate := & computeBeta . InstanceGroupManagersSetInstanceTemplateRequest {
InstanceTemplate : d . Get ( "instance_template" ) . ( string ) ,
}
2019-01-28 22:00:05 +00:00
op , err := config . clientComputeBeta . InstanceGroupManagers . SetInstanceTemplate ( project , zone , name , setInstanceTemplate ) . Do ( )
2018-06-04 22:34:48 +00:00
if err != nil {
return fmt . Errorf ( "Error updating InstanceGroupManager: %s" , err )
}
// Wait for the operation to complete
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Updating InstanceGroupManager" )
2018-06-04 22:34:48 +00:00
if err != nil {
return err
}
updateStrategy := d . Get ( "update_strategy" ) . ( string )
2019-01-28 22:00:05 +00:00
err = performZoneUpdate ( config , name , updateStrategy , project , zone )
2019-02-15 00:00:35 +00:00
if err != nil {
return err
}
2018-06-04 22:34:48 +00:00
d . SetPartial ( "instance_template" )
}
2015-02-16 16:06:23 +00:00
d . Partial ( false )
2015-07-28 00:47:10 +00:00
return resourceComputeInstanceGroupManagerRead ( d , meta )
2015-02-16 16:06:23 +00:00
}
2015-07-28 00:47:10 +00:00
func resourceComputeInstanceGroupManagerDelete ( d * schema . ResourceData , meta interface { } ) error {
2015-02-16 16:06:23 +00:00
config := meta . ( * Config )
2019-01-28 22:00:05 +00:00
if err := parseImportId ( [ ] string { "(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<name>[^/]+)" , "(?P<project>[^/]+)/(?P<name>[^/]+)" , "(?P<name>[^/]+)" } , d , config ) ; err != nil {
2016-04-10 16:59:57 +00:00
return err
}
2019-01-28 22:00:05 +00:00
project , err := getProject ( d , config )
if err != nil {
return err
2018-10-16 23:53:48 +00:00
}
2019-01-28 22:00:05 +00:00
zone , _ := getZone ( d , config )
name := d . Get ( "name" ) . ( string )
2017-07-26 20:37:59 +00:00
2019-01-28 22:00:05 +00:00
op , err := config . clientComputeBeta . InstanceGroupManagers . Delete ( project , zone , name ) . Do ( )
2018-05-09 18:24:40 +00:00
attempt := 0
for err != nil && attempt < 20 {
attempt ++
time . Sleep ( 2000 * time . Millisecond )
2019-01-28 22:00:05 +00:00
op , err = config . clientComputeBeta . InstanceGroupManagers . Delete ( project , zone , name ) . Do ( )
2016-08-05 18:30:41 +00:00
}
2017-07-26 20:37:59 +00:00
2015-02-16 16:06:23 +00:00
if err != nil {
return fmt . Errorf ( "Error deleting instance group manager: %s" , err )
}
2015-10-23 19:06:46 +00:00
currentSize := int64 ( d . Get ( "target_size" ) . ( int ) )
2015-02-16 16:06:23 +00:00
// Wait for the operation to complete
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Deleting InstanceGroupManager" )
2015-10-23 19:06:46 +00:00
for err != nil && currentSize > 0 {
if ! strings . Contains ( err . Error ( ) , "timeout" ) {
2015-10-29 22:10:44 +00:00
return err
2015-10-23 19:06:46 +00:00
}
2019-02-15 00:00:35 +00:00
instanceGroup , igErr := config . clientComputeBeta . InstanceGroups . Get (
2019-01-28 22:00:05 +00:00
project , zone , name ) . Do ( )
2019-02-15 00:00:35 +00:00
if igErr != nil {
2018-05-09 18:24:40 +00:00
return fmt . Errorf ( "Error getting instance group size: %s" , err )
2018-05-04 14:51:45 +00:00
}
2018-05-03 19:24:21 +00:00
2018-05-09 18:24:40 +00:00
instanceGroupSize := instanceGroup . Size
2017-07-26 20:37:59 +00:00
if instanceGroupSize >= currentSize {
2015-10-23 19:06:46 +00:00
return fmt . Errorf ( "Error, instance group isn't shrinking during delete" )
}
2018-12-15 02:16:33 +00:00
log . Printf ( "[INFO] timeout occurred, but instance group is shrinking (%d < %d)" , instanceGroupSize , currentSize )
2017-07-26 20:37:59 +00:00
currentSize = instanceGroupSize
2019-01-28 22:00:05 +00:00
err = computeSharedOperationWait ( config . clientCompute , op , project , "Deleting InstanceGroupManager" )
2015-02-16 16:06:23 +00:00
}
d . SetId ( "" )
return nil
}
2017-08-02 17:12:16 +00:00
2018-03-21 19:39:12 +00:00
func resourceInstanceGroupManagerStateImporter ( d * schema . ResourceData , meta interface { } ) ( [ ] * schema . ResourceData , error ) {
d . Set ( "wait_for_instances" , false )
2019-01-28 22:00:05 +00:00
config := meta . ( * Config )
if err := parseImportId ( [ ] string { "(?P<project>[^/]+)/(?P<zone>[^/]+)/(?P<name>[^/]+)" , "(?P<project>[^/]+)/(?P<name>[^/]+)" , "(?P<name>[^/]+)" } , d , config ) ; err != nil {
2018-10-16 23:53:48 +00:00
return nil , err
}
2019-01-28 22:00:05 +00:00
// Replace import id for the resource id
id , err := replaceVars ( d , config , "{{project}}/{{zone}}/{{name}}" )
if err != nil {
return nil , fmt . Errorf ( "Error constructing id: %s" , err )
2018-10-16 23:53:48 +00:00
}
2019-01-28 22:00:05 +00:00
d . SetId ( id )
return [ ] * schema . ResourceData { d } , nil
2018-10-16 23:53:48 +00:00
}