github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/builtin/providers/google/resource_sql_database_instance.go (about)

     1  package google
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/hashicorp/terraform/helper/resource"
     8  	"github.com/hashicorp/terraform/helper/schema"
     9  
    10  	"google.golang.org/api/googleapi"
    11  	"google.golang.org/api/sqladmin/v1beta4"
    12  )
    13  
    14  func resourceSqlDatabaseInstance() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceSqlDatabaseInstanceCreate,
    17  		Read:   resourceSqlDatabaseInstanceRead,
    18  		Update: resourceSqlDatabaseInstanceUpdate,
    19  		Delete: resourceSqlDatabaseInstanceDelete,
    20  
    21  		Schema: map[string]*schema.Schema{
    22  			"region": &schema.Schema{
    23  				Type:     schema.TypeString,
    24  				Required: true,
    25  				ForceNew: true,
    26  			},
    27  
    28  			"settings": &schema.Schema{
    29  				Type:     schema.TypeList,
    30  				Required: true,
    31  				Elem: &schema.Resource{
    32  					Schema: map[string]*schema.Schema{
    33  						"version": &schema.Schema{
    34  							Type:     schema.TypeInt,
    35  							Computed: true,
    36  						},
    37  						"tier": &schema.Schema{
    38  							Type:     schema.TypeString,
    39  							Required: true,
    40  						},
    41  						"activation_policy": &schema.Schema{
    42  							Type:     schema.TypeString,
    43  							Optional: true,
    44  						},
    45  						"authorized_gae_applications": &schema.Schema{
    46  							Type:     schema.TypeList,
    47  							Optional: true,
    48  							Elem:     &schema.Schema{Type: schema.TypeString},
    49  						},
    50  						"backup_configuration": &schema.Schema{
    51  							Type:     schema.TypeList,
    52  							Optional: true,
    53  							Elem: &schema.Resource{
    54  								Schema: map[string]*schema.Schema{
    55  									"binary_log_enabled": &schema.Schema{
    56  										Type:     schema.TypeBool,
    57  										Optional: true,
    58  									},
    59  									"enabled": &schema.Schema{
    60  										Type:     schema.TypeBool,
    61  										Optional: true,
    62  									},
    63  									"start_time": &schema.Schema{
    64  										Type:     schema.TypeString,
    65  										Optional: true,
    66  									},
    67  								},
    68  							},
    69  						},
    70  						"crash_safe_replication": &schema.Schema{
    71  							Type:     schema.TypeBool,
    72  							Optional: true,
    73  						},
    74  						"database_flags": &schema.Schema{
    75  							Type:     schema.TypeList,
    76  							Optional: true,
    77  							Elem: &schema.Resource{
    78  								Schema: map[string]*schema.Schema{
    79  									"value": &schema.Schema{
    80  										Type:     schema.TypeString,
    81  										Optional: true,
    82  									},
    83  									"name": &schema.Schema{
    84  										Type:     schema.TypeString,
    85  										Optional: true,
    86  									},
    87  								},
    88  							},
    89  						},
    90  						"ip_configuration": &schema.Schema{
    91  							Type:     schema.TypeList,
    92  							Optional: true,
    93  							Elem: &schema.Resource{
    94  								Schema: map[string]*schema.Schema{
    95  									"authorized_networks": &schema.Schema{
    96  										Type:     schema.TypeList,
    97  										Optional: true,
    98  										Elem: &schema.Resource{
    99  											Schema: map[string]*schema.Schema{
   100  												"expiration_time": &schema.Schema{
   101  													Type:     schema.TypeString,
   102  													Optional: true,
   103  												},
   104  												"name": &schema.Schema{
   105  													Type:     schema.TypeString,
   106  													Optional: true,
   107  												},
   108  												"value": &schema.Schema{
   109  													Type:     schema.TypeString,
   110  													Optional: true,
   111  												},
   112  											},
   113  										},
   114  									},
   115  									"ipv4_enabled": &schema.Schema{
   116  										Type:     schema.TypeBool,
   117  										Optional: true,
   118  									},
   119  									"require_ssl": &schema.Schema{
   120  										Type:     schema.TypeBool,
   121  										Optional: true,
   122  									},
   123  								},
   124  							},
   125  						},
   126  						"location_preference": &schema.Schema{
   127  							Type:     schema.TypeList,
   128  							Optional: true,
   129  							Elem: &schema.Resource{
   130  								Schema: map[string]*schema.Schema{
   131  									"follow_gae_application": &schema.Schema{
   132  										Type:     schema.TypeString,
   133  										Optional: true,
   134  									},
   135  									"zone": &schema.Schema{
   136  										Type:     schema.TypeString,
   137  										Optional: true,
   138  									},
   139  								},
   140  							},
   141  						},
   142  						"pricing_plan": &schema.Schema{
   143  							Type:     schema.TypeString,
   144  							Optional: true,
   145  						},
   146  						"replication_type": &schema.Schema{
   147  							Type:     schema.TypeString,
   148  							Optional: true,
   149  						},
   150  					},
   151  				},
   152  			},
   153  
   154  			"database_version": &schema.Schema{
   155  				Type:     schema.TypeString,
   156  				Optional: true,
   157  				Default:  "MYSQL_5_5",
   158  				ForceNew: true,
   159  			},
   160  
   161  			"ip_address": &schema.Schema{
   162  				Type:     schema.TypeList,
   163  				Computed: true,
   164  				Elem: &schema.Resource{
   165  					Schema: map[string]*schema.Schema{
   166  						"ip_address": &schema.Schema{
   167  							Type:     schema.TypeString,
   168  							Computed: true,
   169  						},
   170  						"time_to_retire": &schema.Schema{
   171  							Type:     schema.TypeString,
   172  							Optional: true,
   173  							Computed: true,
   174  						},
   175  					},
   176  				},
   177  			},
   178  
   179  			"name": &schema.Schema{
   180  				Type:     schema.TypeString,
   181  				Optional: true,
   182  				Computed: true,
   183  				ForceNew: true,
   184  			},
   185  
   186  			"master_instance_name": &schema.Schema{
   187  				Type:     schema.TypeString,
   188  				Optional: true,
   189  				ForceNew: true,
   190  			},
   191  
   192  			"project": &schema.Schema{
   193  				Type:     schema.TypeString,
   194  				Optional: true,
   195  				ForceNew: true,
   196  			},
   197  
   198  			"replica_configuration": &schema.Schema{
   199  				Type:     schema.TypeList,
   200  				Optional: true,
   201  				Elem: &schema.Resource{
   202  					Schema: map[string]*schema.Schema{
   203  						"ca_certificate": &schema.Schema{
   204  							Type:     schema.TypeString,
   205  							Optional: true,
   206  							ForceNew: true,
   207  						},
   208  						"client_certificate": &schema.Schema{
   209  							Type:     schema.TypeString,
   210  							Optional: true,
   211  							ForceNew: true,
   212  						},
   213  						"client_key": &schema.Schema{
   214  							Type:     schema.TypeString,
   215  							Optional: true,
   216  							ForceNew: true,
   217  						},
   218  						"connect_retry_interval": &schema.Schema{
   219  							Type:     schema.TypeInt,
   220  							Optional: true,
   221  							ForceNew: true,
   222  						},
   223  						"dump_file_path": &schema.Schema{
   224  							Type:     schema.TypeString,
   225  							Optional: true,
   226  							ForceNew: true,
   227  						},
   228  						"master_heartbeat_period": &schema.Schema{
   229  							Type:     schema.TypeInt,
   230  							Optional: true,
   231  							ForceNew: true,
   232  						},
   233  						"password": &schema.Schema{
   234  							Type:     schema.TypeString,
   235  							Optional: true,
   236  							ForceNew: true,
   237  						},
   238  						"ssl_cipher": &schema.Schema{
   239  							Type:     schema.TypeString,
   240  							Optional: true,
   241  							ForceNew: true,
   242  						},
   243  						"username": &schema.Schema{
   244  							Type:     schema.TypeString,
   245  							Optional: true,
   246  							ForceNew: true,
   247  						},
   248  						"verify_server_certificate": &schema.Schema{
   249  							Type:     schema.TypeBool,
   250  							Optional: true,
   251  							ForceNew: true,
   252  						},
   253  					},
   254  				},
   255  			},
   256  
   257  			"self_link": &schema.Schema{
   258  				Type:     schema.TypeString,
   259  				Computed: true,
   260  			},
   261  		},
   262  	}
   263  }
   264  
   265  func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{}) error {
   266  	config := meta.(*Config)
   267  
   268  	project, err := getProject(d, config)
   269  	if err != nil {
   270  		return err
   271  	}
   272  
   273  	region := d.Get("region").(string)
   274  	databaseVersion := d.Get("database_version").(string)
   275  
   276  	_settingsList := d.Get("settings").([]interface{})
   277  	if len(_settingsList) > 1 {
   278  		return fmt.Errorf("At most one settings block is allowed")
   279  	}
   280  
   281  	_settings := _settingsList[0].(map[string]interface{})
   282  	settings := &sqladmin.Settings{
   283  		Tier: _settings["tier"].(string),
   284  	}
   285  
   286  	if v, ok := _settings["activation_policy"]; ok {
   287  		settings.ActivationPolicy = v.(string)
   288  	}
   289  
   290  	if v, ok := _settings["authorized_gae_applications"]; ok {
   291  		settings.AuthorizedGaeApplications = make([]string, 0)
   292  		for _, app := range v.([]interface{}) {
   293  			settings.AuthorizedGaeApplications = append(settings.AuthorizedGaeApplications,
   294  				app.(string))
   295  		}
   296  	}
   297  
   298  	if v, ok := _settings["backup_configuration"]; ok {
   299  		_backupConfigurationList := v.([]interface{})
   300  		if len(_backupConfigurationList) > 1 {
   301  			return fmt.Errorf("At most one backup_configuration block is allowed")
   302  		}
   303  
   304  		if len(_backupConfigurationList) == 1 && _backupConfigurationList[0] != nil {
   305  			settings.BackupConfiguration = &sqladmin.BackupConfiguration{}
   306  			_backupConfiguration := _backupConfigurationList[0].(map[string]interface{})
   307  
   308  			if vp, okp := _backupConfiguration["binary_log_enabled"]; okp {
   309  				settings.BackupConfiguration.BinaryLogEnabled = vp.(bool)
   310  			}
   311  
   312  			if vp, okp := _backupConfiguration["enabled"]; okp {
   313  				settings.BackupConfiguration.Enabled = vp.(bool)
   314  			}
   315  
   316  			if vp, okp := _backupConfiguration["start_time"]; okp {
   317  				settings.BackupConfiguration.StartTime = vp.(string)
   318  			}
   319  		}
   320  	}
   321  
   322  	if v, ok := _settings["crash_safe_replication"]; ok {
   323  		settings.CrashSafeReplicationEnabled = v.(bool)
   324  	}
   325  
   326  	if v, ok := _settings["database_flags"]; ok {
   327  		settings.DatabaseFlags = make([]*sqladmin.DatabaseFlags, 0)
   328  		_databaseFlagsList := v.([]interface{})
   329  		for _, _flag := range _databaseFlagsList {
   330  			_entry := _flag.(map[string]interface{})
   331  			flag := &sqladmin.DatabaseFlags{}
   332  			if vp, okp := _entry["name"]; okp {
   333  				flag.Name = vp.(string)
   334  			}
   335  
   336  			if vp, okp := _entry["value"]; okp {
   337  				flag.Value = vp.(string)
   338  			}
   339  
   340  			settings.DatabaseFlags = append(settings.DatabaseFlags, flag)
   341  		}
   342  	}
   343  
   344  	if v, ok := _settings["ip_configuration"]; ok {
   345  		_ipConfigurationList := v.([]interface{})
   346  		if len(_ipConfigurationList) > 1 {
   347  			return fmt.Errorf("At most one ip_configuration block is allowed")
   348  		}
   349  
   350  		if len(_ipConfigurationList) == 1 && _ipConfigurationList[0] != nil {
   351  			settings.IpConfiguration = &sqladmin.IpConfiguration{}
   352  			_ipConfiguration := _ipConfigurationList[0].(map[string]interface{})
   353  
   354  			if vp, okp := _ipConfiguration["ipv4_enabled"]; okp {
   355  				settings.IpConfiguration.Ipv4Enabled = vp.(bool)
   356  			}
   357  
   358  			if vp, okp := _ipConfiguration["require_ssl"]; okp {
   359  				settings.IpConfiguration.RequireSsl = vp.(bool)
   360  			}
   361  
   362  			if vp, okp := _ipConfiguration["authorized_networks"]; okp {
   363  				settings.IpConfiguration.AuthorizedNetworks = make([]*sqladmin.AclEntry, 0)
   364  				_authorizedNetworksList := vp.([]interface{})
   365  				for _, _acl := range _authorizedNetworksList {
   366  					_entry := _acl.(map[string]interface{})
   367  					entry := &sqladmin.AclEntry{}
   368  
   369  					if vpp, okpp := _entry["expiration_time"]; okpp {
   370  						entry.ExpirationTime = vpp.(string)
   371  					}
   372  
   373  					if vpp, okpp := _entry["name"]; okpp {
   374  						entry.Name = vpp.(string)
   375  					}
   376  
   377  					if vpp, okpp := _entry["value"]; okpp {
   378  						entry.Value = vpp.(string)
   379  					}
   380  
   381  					settings.IpConfiguration.AuthorizedNetworks = append(
   382  						settings.IpConfiguration.AuthorizedNetworks, entry)
   383  				}
   384  			}
   385  		}
   386  	}
   387  
   388  	if v, ok := _settings["location_preference"]; ok {
   389  		_locationPreferenceList := v.([]interface{})
   390  		if len(_locationPreferenceList) > 1 {
   391  			return fmt.Errorf("At most one location_preference block is allowed")
   392  		}
   393  
   394  		if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil {
   395  			settings.LocationPreference = &sqladmin.LocationPreference{}
   396  			_locationPreference := _locationPreferenceList[0].(map[string]interface{})
   397  
   398  			if vp, okp := _locationPreference["follow_gae_application"]; okp {
   399  				settings.LocationPreference.FollowGaeApplication = vp.(string)
   400  			}
   401  
   402  			if vp, okp := _locationPreference["zone"]; okp {
   403  				settings.LocationPreference.Zone = vp.(string)
   404  			}
   405  		}
   406  	}
   407  
   408  	if v, ok := _settings["pricing_plan"]; ok {
   409  		settings.PricingPlan = v.(string)
   410  	}
   411  
   412  	if v, ok := _settings["replication_type"]; ok {
   413  		settings.ReplicationType = v.(string)
   414  	}
   415  
   416  	instance := &sqladmin.DatabaseInstance{
   417  		Region:          region,
   418  		Settings:        settings,
   419  		DatabaseVersion: databaseVersion,
   420  	}
   421  
   422  	if v, ok := d.GetOk("name"); ok {
   423  		instance.Name = v.(string)
   424  	} else {
   425  		instance.Name = resource.UniqueId()
   426  		d.Set("name", instance.Name)
   427  	}
   428  
   429  	if v, ok := d.GetOk("replica_configuration"); ok {
   430  		_replicaConfigurationList := v.([]interface{})
   431  		if len(_replicaConfigurationList) > 1 {
   432  			return fmt.Errorf("Only one replica_configuration block may be defined")
   433  		}
   434  
   435  		if len(_replicaConfigurationList) == 1 && _replicaConfigurationList[0] != nil {
   436  			replicaConfiguration := &sqladmin.ReplicaConfiguration{}
   437  			mySqlReplicaConfiguration := &sqladmin.MySqlReplicaConfiguration{}
   438  			_replicaConfiguration := _replicaConfigurationList[0].(map[string]interface{})
   439  
   440  			if vp, okp := _replicaConfiguration["ca_certificate"]; okp {
   441  				mySqlReplicaConfiguration.CaCertificate = vp.(string)
   442  			}
   443  
   444  			if vp, okp := _replicaConfiguration["client_certificate"]; okp {
   445  				mySqlReplicaConfiguration.ClientCertificate = vp.(string)
   446  			}
   447  
   448  			if vp, okp := _replicaConfiguration["client_key"]; okp {
   449  				mySqlReplicaConfiguration.ClientKey = vp.(string)
   450  			}
   451  
   452  			if vp, okp := _replicaConfiguration["connect_retry_interval"]; okp {
   453  				mySqlReplicaConfiguration.ConnectRetryInterval = int64(vp.(int))
   454  			}
   455  
   456  			if vp, okp := _replicaConfiguration["dump_file_path"]; okp {
   457  				mySqlReplicaConfiguration.DumpFilePath = vp.(string)
   458  			}
   459  
   460  			if vp, okp := _replicaConfiguration["master_heartbeat_period"]; okp {
   461  				mySqlReplicaConfiguration.MasterHeartbeatPeriod = int64(vp.(int))
   462  			}
   463  
   464  			if vp, okp := _replicaConfiguration["password"]; okp {
   465  				mySqlReplicaConfiguration.Password = vp.(string)
   466  			}
   467  
   468  			if vp, okp := _replicaConfiguration["ssl_cipher"]; okp {
   469  				mySqlReplicaConfiguration.SslCipher = vp.(string)
   470  			}
   471  
   472  			if vp, okp := _replicaConfiguration["username"]; okp {
   473  				mySqlReplicaConfiguration.Username = vp.(string)
   474  			}
   475  
   476  			if vp, okp := _replicaConfiguration["verify_server_certificate"]; okp {
   477  				mySqlReplicaConfiguration.VerifyServerCertificate = vp.(bool)
   478  			}
   479  
   480  			replicaConfiguration.MysqlReplicaConfiguration = mySqlReplicaConfiguration
   481  			instance.ReplicaConfiguration = replicaConfiguration
   482  		}
   483  	}
   484  
   485  	if v, ok := d.GetOk("master_instance_name"); ok {
   486  		instance.MasterInstanceName = v.(string)
   487  	}
   488  
   489  	op, err := config.clientSqlAdmin.Instances.Insert(project, instance).Do()
   490  	if err != nil {
   491  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 409 {
   492  			return fmt.Errorf("Error, the name %s is unavailable because it was used recently", instance.Name)
   493  		} else {
   494  			return fmt.Errorf("Error, failed to create instance %s: %s", instance.Name, err)
   495  		}
   496  	}
   497  
   498  	err = sqladminOperationWait(config, op, "Create Instance")
   499  	if err != nil {
   500  		return err
   501  	}
   502  
   503  	return resourceSqlDatabaseInstanceRead(d, meta)
   504  }
   505  
   506  func resourceSqlDatabaseInstanceRead(d *schema.ResourceData, meta interface{}) error {
   507  	config := meta.(*Config)
   508  
   509  	project, err := getProject(d, config)
   510  	if err != nil {
   511  		return err
   512  	}
   513  
   514  	instance, err := config.clientSqlAdmin.Instances.Get(project,
   515  		d.Get("name").(string)).Do()
   516  
   517  	if err != nil {
   518  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
   519  			log.Printf("[WARN] Removing SQL Database %q because it's gone", d.Get("name").(string))
   520  			// The resource doesn't exist anymore
   521  			d.SetId("")
   522  
   523  			return nil
   524  		}
   525  
   526  		return fmt.Errorf("Error retrieving instance %s: %s",
   527  			d.Get("name").(string), err)
   528  	}
   529  
   530  	_settingsList := d.Get("settings").([]interface{})
   531  	_settings := _settingsList[0].(map[string]interface{})
   532  
   533  	settings := instance.Settings
   534  	_settings["version"] = settings.SettingsVersion
   535  	_settings["tier"] = settings.Tier
   536  
   537  	// Take care to only update attributes that the user has defined explicitly
   538  	if v, ok := _settings["activation_policy"]; ok && len(v.(string)) > 0 {
   539  		_settings["activation_policy"] = settings.ActivationPolicy
   540  	}
   541  
   542  	if v, ok := _settings["authorized_gae_applications"]; ok && len(v.([]interface{})) > 0 {
   543  		_authorized_gae_applications := make([]interface{}, 0)
   544  		for _, app := range settings.AuthorizedGaeApplications {
   545  			_authorized_gae_applications = append(_authorized_gae_applications, app)
   546  		}
   547  		_settings["authorized_gae_applications"] = _authorized_gae_applications
   548  	}
   549  
   550  	if v, ok := _settings["backup_configuration"]; ok {
   551  		_backupConfigurationList := v.([]interface{})
   552  		if len(_backupConfigurationList) > 1 {
   553  			return fmt.Errorf("At most one backup_configuration block is allowed")
   554  		}
   555  
   556  		if len(_backupConfigurationList) == 1 && _backupConfigurationList[0] != nil {
   557  			_backupConfiguration := _backupConfigurationList[0].(map[string]interface{})
   558  
   559  			if vp, okp := _backupConfiguration["binary_log_enabled"]; okp && vp != nil {
   560  				_backupConfiguration["binary_log_enabled"] = settings.BackupConfiguration.BinaryLogEnabled
   561  			}
   562  
   563  			if vp, okp := _backupConfiguration["enabled"]; okp && vp != nil {
   564  				_backupConfiguration["enabled"] = settings.BackupConfiguration.Enabled
   565  			}
   566  
   567  			if vp, okp := _backupConfiguration["start_time"]; okp && vp != nil {
   568  				_backupConfiguration["start_time"] = settings.BackupConfiguration.StartTime
   569  			}
   570  
   571  			_backupConfigurationList[0] = _backupConfiguration
   572  			_settings["backup_configuration"] = _backupConfigurationList
   573  		}
   574  	}
   575  
   576  	if v, ok := _settings["crash_safe_replication"]; ok && v != nil {
   577  		_settings["crash_safe_replication"] = settings.CrashSafeReplicationEnabled
   578  	}
   579  
   580  	if v, ok := _settings["database_flags"]; ok && len(v.([]interface{})) > 0 {
   581  		_flag_map := make(map[string]string)
   582  		// First keep track of localy defined flag pairs
   583  		for _, _flag := range _settings["database_flags"].([]interface{}) {
   584  			_entry := _flag.(map[string]interface{})
   585  			_flag_map[_entry["name"].(string)] = _entry["value"].(string)
   586  		}
   587  
   588  		_database_flags := make([]interface{}, 0)
   589  		// Next read the flag pairs from the server, and reinsert those that
   590  		// correspond to ones defined locally
   591  		for _, entry := range settings.DatabaseFlags {
   592  			if _, okp := _flag_map[entry.Name]; okp {
   593  				_entry := make(map[string]interface{})
   594  				_entry["name"] = entry.Name
   595  				_entry["value"] = entry.Value
   596  				_database_flags = append(_database_flags, _entry)
   597  			}
   598  		}
   599  		_settings["database_flags"] = _database_flags
   600  	}
   601  
   602  	if v, ok := _settings["ip_configuration"]; ok {
   603  		_ipConfigurationList := v.([]interface{})
   604  		if len(_ipConfigurationList) > 1 {
   605  			return fmt.Errorf("At most one ip_configuration block is allowed")
   606  		}
   607  
   608  		if len(_ipConfigurationList) == 1 && _ipConfigurationList[0] != nil {
   609  			_ipConfiguration := _ipConfigurationList[0].(map[string]interface{})
   610  
   611  			if vp, okp := _ipConfiguration["ipv4_enabled"]; okp && vp != nil {
   612  				_ipConfiguration["ipv4_enabled"] = settings.IpConfiguration.Ipv4Enabled
   613  			}
   614  
   615  			if vp, okp := _ipConfiguration["require_ssl"]; okp && vp != nil {
   616  				_ipConfiguration["require_ssl"] = settings.IpConfiguration.RequireSsl
   617  			}
   618  
   619  			if vp, okp := _ipConfiguration["authorized_networks"]; okp && vp != nil {
   620  				_ipc_map := make(map[string]interface{})
   621  				// First keep track of localy defined ip configurations
   622  				for _, _ipc := range _ipConfigurationList {
   623  					_entry := _ipc.(map[string]interface{})
   624  					if _entry["value"] == nil {
   625  						continue
   626  					}
   627  					_value := make(map[string]interface{})
   628  					_value["name"] = _entry["name"]
   629  					_value["expiration_time"] = _entry["expiration_time"]
   630  					// We key on value, since that is the only required part of
   631  					// this 3-tuple
   632  					_ipc_map[_entry["value"].(string)] = _value
   633  				}
   634  				_authorized_networks := make([]interface{}, 0)
   635  				// Next read the network tuples from the server, and reinsert those that
   636  				// correspond to ones defined locally
   637  				for _, entry := range settings.IpConfiguration.AuthorizedNetworks {
   638  					if _, okp := _ipc_map[entry.Value]; okp {
   639  						_entry := make(map[string]interface{})
   640  						_entry["value"] = entry.Value
   641  						_entry["name"] = entry.Name
   642  						_entry["expiration_time"] = entry.ExpirationTime
   643  						_authorized_networks = append(_authorized_networks, _entry)
   644  					}
   645  				}
   646  				_ipConfiguration["authorized_networks"] = _authorized_networks
   647  			}
   648  			_ipConfigurationList[0] = _ipConfiguration
   649  			_settings["ip_configuration"] = _ipConfigurationList
   650  		}
   651  	}
   652  
   653  	if v, ok := _settings["location_preference"]; ok && len(v.([]interface{})) > 0 {
   654  		_locationPreferenceList := v.([]interface{})
   655  		if len(_locationPreferenceList) > 1 {
   656  			return fmt.Errorf("At most one location_preference block is allowed")
   657  		}
   658  
   659  		if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil &&
   660  			settings.LocationPreference != nil {
   661  			_locationPreference := _locationPreferenceList[0].(map[string]interface{})
   662  
   663  			if vp, okp := _locationPreference["follow_gae_application"]; okp && vp != nil {
   664  				_locationPreference["follow_gae_application"] =
   665  					settings.LocationPreference.FollowGaeApplication
   666  			}
   667  
   668  			if vp, okp := _locationPreference["zone"]; okp && vp != nil {
   669  				_locationPreference["zone"] = settings.LocationPreference.Zone
   670  			}
   671  
   672  			_locationPreferenceList[0] = _locationPreference
   673  			_settings["location_preference"] = _locationPreferenceList[0]
   674  		}
   675  	}
   676  
   677  	if v, ok := _settings["pricing_plan"]; ok && len(v.(string)) > 0 {
   678  		_settings["pricing_plan"] = settings.PricingPlan
   679  	}
   680  
   681  	if v, ok := _settings["replication_type"]; ok && len(v.(string)) > 0 {
   682  		_settings["replication_type"] = settings.ReplicationType
   683  	}
   684  
   685  	_settingsList[0] = _settings
   686  	d.Set("settings", _settingsList)
   687  
   688  	if v, ok := d.GetOk("replica_configuration"); ok && v != nil {
   689  		_replicaConfigurationList := v.([]interface{})
   690  		if len(_replicaConfigurationList) > 1 {
   691  			return fmt.Errorf("Only one replica_configuration block may be defined")
   692  		}
   693  
   694  		if len(_replicaConfigurationList) == 1 && _replicaConfigurationList[0] != nil {
   695  			mySqlReplicaConfiguration := instance.ReplicaConfiguration.MysqlReplicaConfiguration
   696  			_replicaConfiguration := _replicaConfigurationList[0].(map[string]interface{})
   697  
   698  			if vp, okp := _replicaConfiguration["ca_certificate"]; okp && vp != nil {
   699  				_replicaConfiguration["ca_certificate"] = mySqlReplicaConfiguration.CaCertificate
   700  			}
   701  
   702  			if vp, okp := _replicaConfiguration["client_certificate"]; okp && vp != nil {
   703  				_replicaConfiguration["client_certificate"] = mySqlReplicaConfiguration.ClientCertificate
   704  			}
   705  
   706  			if vp, okp := _replicaConfiguration["client_key"]; okp && vp != nil {
   707  				_replicaConfiguration["client_key"] = mySqlReplicaConfiguration.ClientKey
   708  			}
   709  
   710  			if vp, okp := _replicaConfiguration["connect_retry_interval"]; okp && vp != nil {
   711  				_replicaConfiguration["connect_retry_interval"] = mySqlReplicaConfiguration.ConnectRetryInterval
   712  			}
   713  
   714  			if vp, okp := _replicaConfiguration["dump_file_path"]; okp && vp != nil {
   715  				_replicaConfiguration["dump_file_path"] = mySqlReplicaConfiguration.DumpFilePath
   716  			}
   717  
   718  			if vp, okp := _replicaConfiguration["master_heartbeat_period"]; okp && vp != nil {
   719  				_replicaConfiguration["master_heartbeat_period"] = mySqlReplicaConfiguration.MasterHeartbeatPeriod
   720  			}
   721  
   722  			if vp, okp := _replicaConfiguration["password"]; okp && vp != nil {
   723  				_replicaConfiguration["password"] = mySqlReplicaConfiguration.Password
   724  			}
   725  
   726  			if vp, okp := _replicaConfiguration["ssl_cipher"]; okp && vp != nil {
   727  				_replicaConfiguration["ssl_cipher"] = mySqlReplicaConfiguration.SslCipher
   728  			}
   729  
   730  			if vp, okp := _replicaConfiguration["username"]; okp && vp != nil {
   731  				_replicaConfiguration["username"] = mySqlReplicaConfiguration.Username
   732  			}
   733  
   734  			if vp, okp := _replicaConfiguration["verify_server_certificate"]; okp && vp != nil {
   735  				_replicaConfiguration["verify_server_certificate"] = mySqlReplicaConfiguration.VerifyServerCertificate
   736  			}
   737  
   738  			_replicaConfigurationList[0] = _replicaConfiguration
   739  			d.Set("replica_configuration", _replicaConfigurationList)
   740  		}
   741  	}
   742  
   743  	_ipAddresses := make([]interface{}, len(instance.IpAddresses))
   744  
   745  	for i, ip := range instance.IpAddresses {
   746  		_ipAddress := make(map[string]interface{})
   747  
   748  		_ipAddress["ip_address"] = ip.IpAddress
   749  		_ipAddress["time_to_retire"] = ip.TimeToRetire
   750  
   751  		_ipAddresses[i] = _ipAddress
   752  	}
   753  
   754  	d.Set("ip_address", _ipAddresses)
   755  
   756  	if v, ok := d.GetOk("master_instance_name"); ok && v != nil {
   757  		d.Set("master_instance_name", instance.MasterInstanceName)
   758  	}
   759  
   760  	d.Set("self_link", instance.SelfLink)
   761  	d.SetId(instance.Name)
   762  
   763  	return nil
   764  }
   765  
   766  func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
   767  	config := meta.(*Config)
   768  
   769  	project, err := getProject(d, config)
   770  	if err != nil {
   771  		return err
   772  	}
   773  
   774  	d.Partial(true)
   775  
   776  	instance, err := config.clientSqlAdmin.Instances.Get(project,
   777  		d.Get("name").(string)).Do()
   778  
   779  	if err != nil {
   780  		return fmt.Errorf("Error retrieving instance %s: %s",
   781  			d.Get("name").(string), err)
   782  	}
   783  
   784  	if d.HasChange("settings") {
   785  		_oListCast, _settingsListCast := d.GetChange("settings")
   786  		_oList := _oListCast.([]interface{})
   787  		_o := _oList[0].(map[string]interface{})
   788  		_settingsList := _settingsListCast.([]interface{})
   789  		if len(_settingsList) > 1 {
   790  			return fmt.Errorf("At most one settings block is allowed")
   791  		}
   792  
   793  		_settings := _settingsList[0].(map[string]interface{})
   794  		settings := &sqladmin.Settings{
   795  			Tier:            _settings["tier"].(string),
   796  			SettingsVersion: instance.Settings.SettingsVersion,
   797  		}
   798  
   799  		if v, ok := _settings["activation_policy"]; ok {
   800  			settings.ActivationPolicy = v.(string)
   801  		}
   802  
   803  		if v, ok := _settings["authorized_gae_applications"]; ok {
   804  			settings.AuthorizedGaeApplications = make([]string, 0)
   805  			for _, app := range v.([]interface{}) {
   806  				settings.AuthorizedGaeApplications = append(settings.AuthorizedGaeApplications,
   807  					app.(string))
   808  			}
   809  		}
   810  
   811  		if v, ok := _settings["backup_configuration"]; ok {
   812  			_backupConfigurationList := v.([]interface{})
   813  			if len(_backupConfigurationList) > 1 {
   814  				return fmt.Errorf("At most one backup_configuration block is allowed")
   815  			}
   816  
   817  			if len(_backupConfigurationList) == 1 && _backupConfigurationList[0] != nil {
   818  				settings.BackupConfiguration = &sqladmin.BackupConfiguration{}
   819  				_backupConfiguration := _backupConfigurationList[0].(map[string]interface{})
   820  
   821  				if vp, okp := _backupConfiguration["binary_log_enabled"]; okp {
   822  					settings.BackupConfiguration.BinaryLogEnabled = vp.(bool)
   823  				}
   824  
   825  				if vp, okp := _backupConfiguration["enabled"]; okp {
   826  					settings.BackupConfiguration.Enabled = vp.(bool)
   827  				}
   828  
   829  				if vp, okp := _backupConfiguration["start_time"]; okp {
   830  					settings.BackupConfiguration.StartTime = vp.(string)
   831  				}
   832  			}
   833  		}
   834  
   835  		if v, ok := _settings["crash_safe_replication"]; ok {
   836  			settings.CrashSafeReplicationEnabled = v.(bool)
   837  		}
   838  
   839  		_oldDatabaseFlags := make([]interface{}, 0)
   840  		if ov, ook := _o["database_flags"]; ook {
   841  			_oldDatabaseFlags = ov.([]interface{})
   842  		}
   843  
   844  		if v, ok := _settings["database_flags"]; ok || len(_oldDatabaseFlags) > 0 {
   845  			oldDatabaseFlags := settings.DatabaseFlags
   846  			settings.DatabaseFlags = make([]*sqladmin.DatabaseFlags, 0)
   847  			_databaseFlagsList := make([]interface{}, 0)
   848  			if v != nil {
   849  				_databaseFlagsList = v.([]interface{})
   850  			}
   851  
   852  			_odbf_map := make(map[string]interface{})
   853  			for _, _dbf := range _oldDatabaseFlags {
   854  				_entry := _dbf.(map[string]interface{})
   855  				_odbf_map[_entry["name"].(string)] = true
   856  			}
   857  
   858  			// First read the flags from the server, and reinsert those that
   859  			// were not previously defined
   860  			for _, entry := range oldDatabaseFlags {
   861  				_, ok_old := _odbf_map[entry.Name]
   862  				if !ok_old {
   863  					settings.DatabaseFlags = append(
   864  						settings.DatabaseFlags, entry)
   865  				}
   866  			}
   867  			// finally, insert only those that were previously defined
   868  			// and are still defined.
   869  			for _, _flag := range _databaseFlagsList {
   870  				_entry := _flag.(map[string]interface{})
   871  				flag := &sqladmin.DatabaseFlags{}
   872  				if vp, okp := _entry["name"]; okp {
   873  					flag.Name = vp.(string)
   874  				}
   875  
   876  				if vp, okp := _entry["value"]; okp {
   877  					flag.Value = vp.(string)
   878  				}
   879  
   880  				settings.DatabaseFlags = append(settings.DatabaseFlags, flag)
   881  			}
   882  		}
   883  
   884  		if v, ok := _settings["ip_configuration"]; ok {
   885  			_ipConfigurationList := v.([]interface{})
   886  			if len(_ipConfigurationList) > 1 {
   887  				return fmt.Errorf("At most one ip_configuration block is allowed")
   888  			}
   889  
   890  			if len(_ipConfigurationList) == 1 && _ipConfigurationList[0] != nil {
   891  				settings.IpConfiguration = &sqladmin.IpConfiguration{}
   892  				_ipConfiguration := _ipConfigurationList[0].(map[string]interface{})
   893  
   894  				if vp, okp := _ipConfiguration["ipv4_enabled"]; okp {
   895  					settings.IpConfiguration.Ipv4Enabled = vp.(bool)
   896  				}
   897  
   898  				if vp, okp := _ipConfiguration["require_ssl"]; okp {
   899  					settings.IpConfiguration.RequireSsl = vp.(bool)
   900  				}
   901  
   902  				_oldAuthorizedNetworkList := make([]interface{}, 0)
   903  				if ov, ook := _o["ip_configuration"]; ook {
   904  					_oldIpConfList := ov.([]interface{})
   905  					if len(_oldIpConfList) > 0 {
   906  						_oldIpConf := _oldIpConfList[0].(map[string]interface{})
   907  						if ovp, ookp := _oldIpConf["authorized_networks"]; ookp {
   908  							_oldAuthorizedNetworkList = ovp.([]interface{})
   909  						}
   910  					}
   911  				}
   912  
   913  				if vp, okp := _ipConfiguration["authorized_networks"]; okp || len(_oldAuthorizedNetworkList) > 0 {
   914  					oldAuthorizedNetworks := settings.IpConfiguration.AuthorizedNetworks
   915  					settings.IpConfiguration.AuthorizedNetworks = make([]*sqladmin.AclEntry, 0)
   916  
   917  					_authorizedNetworksList := make([]interface{}, 0)
   918  					if vp != nil {
   919  						_authorizedNetworksList = vp.([]interface{})
   920  					}
   921  					_oipc_map := make(map[string]interface{})
   922  					for _, _ipc := range _oldAuthorizedNetworkList {
   923  						_entry := _ipc.(map[string]interface{})
   924  						_oipc_map[_entry["value"].(string)] = true
   925  					}
   926  					// Next read the network tuples from the server, and reinsert those that
   927  					// were not previously defined
   928  					for _, entry := range oldAuthorizedNetworks {
   929  						_, ok_old := _oipc_map[entry.Value]
   930  						if !ok_old {
   931  							settings.IpConfiguration.AuthorizedNetworks = append(
   932  								settings.IpConfiguration.AuthorizedNetworks, entry)
   933  						}
   934  					}
   935  					// finally, insert only those that were previously defined
   936  					// and are still defined.
   937  					for _, _ipc := range _authorizedNetworksList {
   938  						_entry := _ipc.(map[string]interface{})
   939  						if _, ok_old := _oipc_map[_entry["value"].(string)]; ok_old {
   940  							entry := &sqladmin.AclEntry{}
   941  
   942  							if vpp, okpp := _entry["expiration_time"]; okpp {
   943  								entry.ExpirationTime = vpp.(string)
   944  							}
   945  
   946  							if vpp, okpp := _entry["name"]; okpp {
   947  								entry.Name = vpp.(string)
   948  							}
   949  
   950  							if vpp, okpp := _entry["value"]; okpp {
   951  								entry.Value = vpp.(string)
   952  							}
   953  
   954  							settings.IpConfiguration.AuthorizedNetworks = append(
   955  								settings.IpConfiguration.AuthorizedNetworks, entry)
   956  						}
   957  					}
   958  				}
   959  			}
   960  		}
   961  
   962  		if v, ok := _settings["location_preference"]; ok {
   963  			_locationPreferenceList := v.([]interface{})
   964  			if len(_locationPreferenceList) > 1 {
   965  				return fmt.Errorf("At most one location_preference block is allowed")
   966  			}
   967  
   968  			if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil {
   969  				settings.LocationPreference = &sqladmin.LocationPreference{}
   970  				_locationPreference := _locationPreferenceList[0].(map[string]interface{})
   971  
   972  				if vp, okp := _locationPreference["follow_gae_application"]; okp {
   973  					settings.LocationPreference.FollowGaeApplication = vp.(string)
   974  				}
   975  
   976  				if vp, okp := _locationPreference["zone"]; okp {
   977  					settings.LocationPreference.Zone = vp.(string)
   978  				}
   979  			}
   980  		}
   981  
   982  		if v, ok := _settings["pricing_plan"]; ok {
   983  			settings.PricingPlan = v.(string)
   984  		}
   985  
   986  		if v, ok := _settings["replication_type"]; ok {
   987  			settings.ReplicationType = v.(string)
   988  		}
   989  
   990  		instance.Settings = settings
   991  	}
   992  
   993  	d.Partial(false)
   994  
   995  	op, err := config.clientSqlAdmin.Instances.Update(project, instance.Name, instance).Do()
   996  	if err != nil {
   997  		return fmt.Errorf("Error, failed to update instance %s: %s", instance.Name, err)
   998  	}
   999  
  1000  	err = sqladminOperationWait(config, op, "Create Instance")
  1001  	if err != nil {
  1002  		return err
  1003  	}
  1004  
  1005  	return resourceSqlDatabaseInstanceRead(d, meta)
  1006  }
  1007  
  1008  func resourceSqlDatabaseInstanceDelete(d *schema.ResourceData, meta interface{}) error {
  1009  	config := meta.(*Config)
  1010  
  1011  	project, err := getProject(d, config)
  1012  	if err != nil {
  1013  		return err
  1014  	}
  1015  
  1016  	op, err := config.clientSqlAdmin.Instances.Delete(project, d.Get("name").(string)).Do()
  1017  
  1018  	if err != nil {
  1019  		return fmt.Errorf("Error, failed to delete instance %s: %s", d.Get("name").(string), err)
  1020  	}
  1021  
  1022  	err = sqladminOperationWait(config, op, "Delete Instance")
  1023  	if err != nil {
  1024  		return err
  1025  	}
  1026  
  1027  	return nil
  1028  }