provider/google-cloud: Add maintenance window (#12042)
* provider/google-cloud: Add maintenance window Allows specification of the `maintenance_window` within the `settings` block. This controls when Google will restart a database in order to apply updates. It is also possible to select an `update_track` to relatively control updating between instances in the same project. * Adjustments as suggested in code review.
This commit is contained in:
parent
a2682bc94b
commit
bfdeae0e33
|
@ -153,6 +153,33 @@ func resourceSqlDatabaseInstance() *schema.Resource {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"maintenance_window": &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Optional: true,
|
||||||
|
MaxItems: 1,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
"day": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
return validateNumericRange(v, k, 1, 7)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"hour": &schema.Schema{
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Optional: true,
|
||||||
|
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
return validateNumericRange(v, k, 0, 23)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"update_track": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
"pricing_plan": &schema.Schema{
|
"pricing_plan": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -431,6 +458,25 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := _settings["maintenance_window"]; ok && len(v.([]interface{})) > 0 {
|
||||||
|
settings.MaintenanceWindow = &sqladmin.MaintenanceWindow{}
|
||||||
|
_maintenanceWindow := v.([]interface{})[0].(map[string]interface{})
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["day"]; okp {
|
||||||
|
settings.MaintenanceWindow.Day = int64(vp.(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["hour"]; okp {
|
||||||
|
settings.MaintenanceWindow.Hour = int64(vp.(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, ok := _maintenanceWindow["update_track"]; ok {
|
||||||
|
if len(vp.(string)) > 0 {
|
||||||
|
settings.MaintenanceWindow.UpdateTrack = vp.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := _settings["pricing_plan"]; ok {
|
if v, ok := _settings["pricing_plan"]; ok {
|
||||||
settings.PricingPlan = v.(string)
|
settings.PricingPlan = v.(string)
|
||||||
}
|
}
|
||||||
|
@ -745,6 +791,25 @@ func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := _settings["maintenance_window"]; ok && len(v.([]interface{})) > 0 &&
|
||||||
|
settings.MaintenanceWindow != nil {
|
||||||
|
_maintenanceWindow := v.([]interface{})[0].(map[string]interface{})
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["day"]; okp && vp != nil {
|
||||||
|
_maintenanceWindow["day"] = settings.MaintenanceWindow.Day
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["hour"]; okp && vp != nil {
|
||||||
|
_maintenanceWindow["hour"] = settings.MaintenanceWindow.Hour
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, ok := _maintenanceWindow["update_track"]; ok && vp != nil {
|
||||||
|
if len(vp.(string)) > 0 {
|
||||||
|
_maintenanceWindow["update_track"] = settings.MaintenanceWindow.UpdateTrack
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := _settings["pricing_plan"]; ok && len(v.(string)) > 0 {
|
if v, ok := _settings["pricing_plan"]; ok && len(v.(string)) > 0 {
|
||||||
_settings["pricing_plan"] = settings.PricingPlan
|
_settings["pricing_plan"] = settings.PricingPlan
|
||||||
}
|
}
|
||||||
|
@ -1062,6 +1127,25 @@ func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v, ok := _settings["maintenance_window"]; ok && len(v.([]interface{})) > 0 {
|
||||||
|
settings.MaintenanceWindow = &sqladmin.MaintenanceWindow{}
|
||||||
|
_maintenanceWindow := v.([]interface{})[0].(map[string]interface{})
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["day"]; okp {
|
||||||
|
settings.MaintenanceWindow.Day = int64(vp.(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, okp := _maintenanceWindow["hour"]; okp {
|
||||||
|
settings.MaintenanceWindow.Hour = int64(vp.(int))
|
||||||
|
}
|
||||||
|
|
||||||
|
if vp, ok := _maintenanceWindow["update_track"]; ok {
|
||||||
|
if len(vp.(string)) > 0 {
|
||||||
|
settings.MaintenanceWindow.UpdateTrack = vp.(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if v, ok := _settings["pricing_plan"]; ok {
|
if v, ok := _settings["pricing_plan"]; ok {
|
||||||
settings.PricingPlan = v.(string)
|
settings.PricingPlan = v.(string)
|
||||||
}
|
}
|
||||||
|
@ -1109,3 +1193,12 @@ func resourceSqlDatabaseInstanceDelete(d *schema.ResourceData, meta interface{})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateNumericRange(v interface{}, k string, min int, max int) (ws []string, errors []error) {
|
||||||
|
value := v.(int)
|
||||||
|
if min > value || value > max {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q outside range %d-%d.", k, min, max))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -162,6 +162,29 @@ func TestAccGoogleSqlDatabaseInstance_diskspecs(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccGoogleSqlDatabaseInstance_maintenance(t *testing.T) {
|
||||||
|
var instance sqladmin.DatabaseInstance
|
||||||
|
masterID := acctest.RandInt()
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccGoogleSqlDatabaseInstanceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: fmt.Sprintf(
|
||||||
|
testGoogleSqlDatabaseInstance_maintenance, masterID),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckGoogleSqlDatabaseInstanceExists(
|
||||||
|
"google_sql_database_instance.instance", &instance),
|
||||||
|
testAccCheckGoogleSqlDatabaseInstanceEquals(
|
||||||
|
"google_sql_database_instance.instance", &instance),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccGoogleSqlDatabaseInstance_settings_upgrade(t *testing.T) {
|
func TestAccGoogleSqlDatabaseInstance_settings_upgrade(t *testing.T) {
|
||||||
var instance sqladmin.DatabaseInstance
|
var instance sqladmin.DatabaseInstance
|
||||||
databaseID := acctest.RandInt()
|
databaseID := acctest.RandInt()
|
||||||
|
@ -359,6 +382,26 @@ func testAccCheckGoogleSqlDatabaseInstanceEquals(n string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if instance.Settings.MaintenanceWindow != nil {
|
||||||
|
server = strconv.FormatInt(instance.Settings.MaintenanceWindow.Day, 10)
|
||||||
|
local = attributes["settings.0.maintenance_window.0.day"]
|
||||||
|
if server != local && len(server) > 0 && len(local) > 0 {
|
||||||
|
return fmt.Errorf("Error settings.maintenance_window.day mismatch, (%s, %s)", server, local)
|
||||||
|
}
|
||||||
|
|
||||||
|
server = strconv.FormatInt(instance.Settings.MaintenanceWindow.Hour, 10)
|
||||||
|
local = attributes["settings.0.maintenance_window.0.hour"]
|
||||||
|
if server != local && len(server) > 0 && len(local) > 0 {
|
||||||
|
return fmt.Errorf("Error settings.maintenance_window.hour mismatch, (%s, %s)", server, local)
|
||||||
|
}
|
||||||
|
|
||||||
|
server = instance.Settings.MaintenanceWindow.UpdateTrack
|
||||||
|
local = attributes["settings.0.maintenance_window.0.update_track"]
|
||||||
|
if server != local && len(server) > 0 && len(local) > 0 {
|
||||||
|
return fmt.Errorf("Error settings.maintenance_window.update_track mismatch, (%s, %s)", server, local)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
server = instance.Settings.PricingPlan
|
server = instance.Settings.PricingPlan
|
||||||
local = attributes["settings.0.pricing_plan"]
|
local = attributes["settings.0.pricing_plan"]
|
||||||
if server != local && len(server) > 0 && len(local) > 0 {
|
if server != local && len(server) > 0 && len(local) > 0 {
|
||||||
|
@ -639,6 +682,23 @@ resource "google_sql_database_instance" "instance" {
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var testGoogleSqlDatabaseInstance_maintenance = `
|
||||||
|
resource "google_sql_database_instance" "instance" {
|
||||||
|
name = "tf-lw-%d"
|
||||||
|
region = "us-central1"
|
||||||
|
|
||||||
|
settings {
|
||||||
|
tier = "db-f1-micro"
|
||||||
|
|
||||||
|
maintenance_window {
|
||||||
|
day = 7
|
||||||
|
hour = 3
|
||||||
|
update_track = "canary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
var testGoogleSqlDatabaseInstance_authNets_step1 = `
|
var testGoogleSqlDatabaseInstance_authNets_step1 = `
|
||||||
resource "google_sql_database_instance" "instance" {
|
resource "google_sql_database_instance" "instance" {
|
||||||
name = "tf-lw-%d"
|
name = "tf-lw-%d"
|
||||||
|
|
|
@ -134,6 +134,17 @@ The optional `settings.location_preference` subblock supports:
|
||||||
* `zone` - (Optional) The preferred compute engine
|
* `zone` - (Optional) The preferred compute engine
|
||||||
[zone](https://cloud.google.com/compute/docs/zones?hl=en).
|
[zone](https://cloud.google.com/compute/docs/zones?hl=en).
|
||||||
|
|
||||||
|
The optional `settings.maintenance_window` subblock for Second Generation
|
||||||
|
instances declares a one-hour [maintenance window](https://cloud.google.com/sql/docs/instance-settings?hl=en#maintenance-window-2ndgen)
|
||||||
|
when an Instance can automatically restart to apply updates. It supports:
|
||||||
|
|
||||||
|
* `day` - (Optional) Day of week (`1-7`), starting on Monday
|
||||||
|
|
||||||
|
* `hour` - (Optional) Hour of day (`0-23`), ignored if `day` not set
|
||||||
|
|
||||||
|
* `update_track` - (Optional) Receive updates earlier (`canary`) or later
|
||||||
|
(`stable`)
|
||||||
|
|
||||||
The optional `replica_configuration` block must have `master_instance_name` set
|
The optional `replica_configuration` block must have `master_instance_name` set
|
||||||
to work, cannot be updated, and supports:
|
to work, cannot be updated, and supports:
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue