github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/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_6",
   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  				_authorizedNetworksList := vp.([]interface{})
   621  				_ipc_map := make(map[string]interface{})
   622  				// First keep track of locally defined ip configurations
   623  				for _, _ipc := range _authorizedNetworksList {
   624  					if _ipc == nil {
   625  						continue
   626  					}
   627  					_entry := _ipc.(map[string]interface{})
   628  					if _entry["value"] == nil {
   629  						continue
   630  					}
   631  					_value := make(map[string]interface{})
   632  					_value["name"] = _entry["name"]
   633  					_value["expiration_time"] = _entry["expiration_time"]
   634  					// We key on value, since that is the only required part of
   635  					// this 3-tuple
   636  					_ipc_map[_entry["value"].(string)] = _value
   637  				}
   638  				_authorized_networks := make([]interface{}, 0)
   639  				// Next read the network tuples from the server, and reinsert those that
   640  				// correspond to ones defined locally
   641  				for _, entry := range settings.IpConfiguration.AuthorizedNetworks {
   642  					if _, okp := _ipc_map[entry.Value]; okp {
   643  						_entry := make(map[string]interface{})
   644  						_entry["value"] = entry.Value
   645  						_entry["name"] = entry.Name
   646  						_entry["expiration_time"] = entry.ExpirationTime
   647  						_authorized_networks = append(_authorized_networks, _entry)
   648  					}
   649  				}
   650  				_ipConfiguration["authorized_networks"] = _authorized_networks
   651  			}
   652  			_ipConfigurationList[0] = _ipConfiguration
   653  			_settings["ip_configuration"] = _ipConfigurationList
   654  		}
   655  	}
   656  
   657  	if v, ok := _settings["location_preference"]; ok && len(v.([]interface{})) > 0 {
   658  		_locationPreferenceList := v.([]interface{})
   659  		if len(_locationPreferenceList) > 1 {
   660  			return fmt.Errorf("At most one location_preference block is allowed")
   661  		}
   662  
   663  		if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil &&
   664  			settings.LocationPreference != nil {
   665  			_locationPreference := _locationPreferenceList[0].(map[string]interface{})
   666  
   667  			if vp, okp := _locationPreference["follow_gae_application"]; okp && vp != nil {
   668  				_locationPreference["follow_gae_application"] =
   669  					settings.LocationPreference.FollowGaeApplication
   670  			}
   671  
   672  			if vp, okp := _locationPreference["zone"]; okp && vp != nil {
   673  				_locationPreference["zone"] = settings.LocationPreference.Zone
   674  			}
   675  
   676  			_locationPreferenceList[0] = _locationPreference
   677  			_settings["location_preference"] = _locationPreferenceList[0]
   678  		}
   679  	}
   680  
   681  	if v, ok := _settings["pricing_plan"]; ok && len(v.(string)) > 0 {
   682  		_settings["pricing_plan"] = settings.PricingPlan
   683  	}
   684  
   685  	if v, ok := _settings["replication_type"]; ok && len(v.(string)) > 0 {
   686  		_settings["replication_type"] = settings.ReplicationType
   687  	}
   688  
   689  	_settingsList[0] = _settings
   690  	d.Set("settings", _settingsList)
   691  
   692  	if v, ok := d.GetOk("replica_configuration"); ok && v != nil {
   693  		_replicaConfigurationList := v.([]interface{})
   694  		if len(_replicaConfigurationList) > 1 {
   695  			return fmt.Errorf("Only one replica_configuration block may be defined")
   696  		}
   697  
   698  		if len(_replicaConfigurationList) == 1 && _replicaConfigurationList[0] != nil {
   699  			mySqlReplicaConfiguration := instance.ReplicaConfiguration.MysqlReplicaConfiguration
   700  			_replicaConfiguration := _replicaConfigurationList[0].(map[string]interface{})
   701  
   702  			if vp, okp := _replicaConfiguration["ca_certificate"]; okp && vp != nil {
   703  				_replicaConfiguration["ca_certificate"] = mySqlReplicaConfiguration.CaCertificate
   704  			}
   705  
   706  			if vp, okp := _replicaConfiguration["client_certificate"]; okp && vp != nil {
   707  				_replicaConfiguration["client_certificate"] = mySqlReplicaConfiguration.ClientCertificate
   708  			}
   709  
   710  			if vp, okp := _replicaConfiguration["client_key"]; okp && vp != nil {
   711  				_replicaConfiguration["client_key"] = mySqlReplicaConfiguration.ClientKey
   712  			}
   713  
   714  			if vp, okp := _replicaConfiguration["connect_retry_interval"]; okp && vp != nil {
   715  				_replicaConfiguration["connect_retry_interval"] = mySqlReplicaConfiguration.ConnectRetryInterval
   716  			}
   717  
   718  			if vp, okp := _replicaConfiguration["dump_file_path"]; okp && vp != nil {
   719  				_replicaConfiguration["dump_file_path"] = mySqlReplicaConfiguration.DumpFilePath
   720  			}
   721  
   722  			if vp, okp := _replicaConfiguration["master_heartbeat_period"]; okp && vp != nil {
   723  				_replicaConfiguration["master_heartbeat_period"] = mySqlReplicaConfiguration.MasterHeartbeatPeriod
   724  			}
   725  
   726  			if vp, okp := _replicaConfiguration["password"]; okp && vp != nil {
   727  				_replicaConfiguration["password"] = mySqlReplicaConfiguration.Password
   728  			}
   729  
   730  			if vp, okp := _replicaConfiguration["ssl_cipher"]; okp && vp != nil {
   731  				_replicaConfiguration["ssl_cipher"] = mySqlReplicaConfiguration.SslCipher
   732  			}
   733  
   734  			if vp, okp := _replicaConfiguration["username"]; okp && vp != nil {
   735  				_replicaConfiguration["username"] = mySqlReplicaConfiguration.Username
   736  			}
   737  
   738  			if vp, okp := _replicaConfiguration["verify_server_certificate"]; okp && vp != nil {
   739  				_replicaConfiguration["verify_server_certificate"] = mySqlReplicaConfiguration.VerifyServerCertificate
   740  			}
   741  
   742  			_replicaConfigurationList[0] = _replicaConfiguration
   743  			d.Set("replica_configuration", _replicaConfigurationList)
   744  		}
   745  	}
   746  
   747  	_ipAddresses := make([]interface{}, len(instance.IpAddresses))
   748  
   749  	for i, ip := range instance.IpAddresses {
   750  		_ipAddress := make(map[string]interface{})
   751  
   752  		_ipAddress["ip_address"] = ip.IpAddress
   753  		_ipAddress["time_to_retire"] = ip.TimeToRetire
   754  
   755  		_ipAddresses[i] = _ipAddress
   756  	}
   757  
   758  	d.Set("ip_address", _ipAddresses)
   759  
   760  	if v, ok := d.GetOk("master_instance_name"); ok && v != nil {
   761  		d.Set("master_instance_name", instance.MasterInstanceName)
   762  	}
   763  
   764  	d.Set("self_link", instance.SelfLink)
   765  	d.SetId(instance.Name)
   766  
   767  	return nil
   768  }
   769  
   770  func resourceSqlDatabaseInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
   771  	config := meta.(*Config)
   772  
   773  	project, err := getProject(d, config)
   774  	if err != nil {
   775  		return err
   776  	}
   777  
   778  	d.Partial(true)
   779  
   780  	instance, err := config.clientSqlAdmin.Instances.Get(project,
   781  		d.Get("name").(string)).Do()
   782  
   783  	if err != nil {
   784  		return fmt.Errorf("Error retrieving instance %s: %s",
   785  			d.Get("name").(string), err)
   786  	}
   787  
   788  	if d.HasChange("settings") {
   789  		_oListCast, _settingsListCast := d.GetChange("settings")
   790  		_oList := _oListCast.([]interface{})
   791  		_o := _oList[0].(map[string]interface{})
   792  		_settingsList := _settingsListCast.([]interface{})
   793  		if len(_settingsList) > 1 {
   794  			return fmt.Errorf("At most one settings block is allowed")
   795  		}
   796  
   797  		_settings := _settingsList[0].(map[string]interface{})
   798  		settings := &sqladmin.Settings{
   799  			Tier:            _settings["tier"].(string),
   800  			SettingsVersion: instance.Settings.SettingsVersion,
   801  		}
   802  
   803  		if v, ok := _settings["activation_policy"]; ok {
   804  			settings.ActivationPolicy = v.(string)
   805  		}
   806  
   807  		if v, ok := _settings["authorized_gae_applications"]; ok {
   808  			settings.AuthorizedGaeApplications = make([]string, 0)
   809  			for _, app := range v.([]interface{}) {
   810  				settings.AuthorizedGaeApplications = append(settings.AuthorizedGaeApplications,
   811  					app.(string))
   812  			}
   813  		}
   814  
   815  		if v, ok := _settings["backup_configuration"]; ok {
   816  			_backupConfigurationList := v.([]interface{})
   817  			if len(_backupConfigurationList) > 1 {
   818  				return fmt.Errorf("At most one backup_configuration block is allowed")
   819  			}
   820  
   821  			if len(_backupConfigurationList) == 1 && _backupConfigurationList[0] != nil {
   822  				settings.BackupConfiguration = &sqladmin.BackupConfiguration{}
   823  				_backupConfiguration := _backupConfigurationList[0].(map[string]interface{})
   824  
   825  				if vp, okp := _backupConfiguration["binary_log_enabled"]; okp {
   826  					settings.BackupConfiguration.BinaryLogEnabled = vp.(bool)
   827  				}
   828  
   829  				if vp, okp := _backupConfiguration["enabled"]; okp {
   830  					settings.BackupConfiguration.Enabled = vp.(bool)
   831  				}
   832  
   833  				if vp, okp := _backupConfiguration["start_time"]; okp {
   834  					settings.BackupConfiguration.StartTime = vp.(string)
   835  				}
   836  			}
   837  		}
   838  
   839  		if v, ok := _settings["crash_safe_replication"]; ok {
   840  			settings.CrashSafeReplicationEnabled = v.(bool)
   841  		}
   842  
   843  		_oldDatabaseFlags := make([]interface{}, 0)
   844  		if ov, ook := _o["database_flags"]; ook {
   845  			_oldDatabaseFlags = ov.([]interface{})
   846  		}
   847  
   848  		if v, ok := _settings["database_flags"]; ok || len(_oldDatabaseFlags) > 0 {
   849  			oldDatabaseFlags := settings.DatabaseFlags
   850  			settings.DatabaseFlags = make([]*sqladmin.DatabaseFlags, 0)
   851  			_databaseFlagsList := make([]interface{}, 0)
   852  			if v != nil {
   853  				_databaseFlagsList = v.([]interface{})
   854  			}
   855  
   856  			_odbf_map := make(map[string]interface{})
   857  			for _, _dbf := range _oldDatabaseFlags {
   858  				_entry := _dbf.(map[string]interface{})
   859  				_odbf_map[_entry["name"].(string)] = true
   860  			}
   861  
   862  			// First read the flags from the server, and reinsert those that
   863  			// were not previously defined
   864  			for _, entry := range oldDatabaseFlags {
   865  				_, ok_old := _odbf_map[entry.Name]
   866  				if !ok_old {
   867  					settings.DatabaseFlags = append(
   868  						settings.DatabaseFlags, entry)
   869  				}
   870  			}
   871  			// finally, insert only those that were previously defined
   872  			// and are still defined.
   873  			for _, _flag := range _databaseFlagsList {
   874  				_entry := _flag.(map[string]interface{})
   875  				flag := &sqladmin.DatabaseFlags{}
   876  				if vp, okp := _entry["name"]; okp {
   877  					flag.Name = vp.(string)
   878  				}
   879  
   880  				if vp, okp := _entry["value"]; okp {
   881  					flag.Value = vp.(string)
   882  				}
   883  
   884  				settings.DatabaseFlags = append(settings.DatabaseFlags, flag)
   885  			}
   886  		}
   887  
   888  		if v, ok := _settings["ip_configuration"]; ok {
   889  			_ipConfigurationList := v.([]interface{})
   890  			if len(_ipConfigurationList) > 1 {
   891  				return fmt.Errorf("At most one ip_configuration block is allowed")
   892  			}
   893  
   894  			if len(_ipConfigurationList) == 1 && _ipConfigurationList[0] != nil {
   895  				settings.IpConfiguration = &sqladmin.IpConfiguration{}
   896  				_ipConfiguration := _ipConfigurationList[0].(map[string]interface{})
   897  
   898  				if vp, okp := _ipConfiguration["ipv4_enabled"]; okp {
   899  					settings.IpConfiguration.Ipv4Enabled = vp.(bool)
   900  				}
   901  
   902  				if vp, okp := _ipConfiguration["require_ssl"]; okp {
   903  					settings.IpConfiguration.RequireSsl = vp.(bool)
   904  				}
   905  
   906  				_oldAuthorizedNetworkList := make([]interface{}, 0)
   907  				if ov, ook := _o["ip_configuration"]; ook {
   908  					_oldIpConfList := ov.([]interface{})
   909  					if len(_oldIpConfList) > 0 {
   910  						_oldIpConf := _oldIpConfList[0].(map[string]interface{})
   911  						if ovp, ookp := _oldIpConf["authorized_networks"]; ookp {
   912  							_oldAuthorizedNetworkList = ovp.([]interface{})
   913  						}
   914  					}
   915  				}
   916  
   917  				if vp, okp := _ipConfiguration["authorized_networks"]; okp || len(_oldAuthorizedNetworkList) > 0 {
   918  					oldAuthorizedNetworks := instance.Settings.IpConfiguration.AuthorizedNetworks
   919  					settings.IpConfiguration.AuthorizedNetworks = make([]*sqladmin.AclEntry, 0)
   920  
   921  					_authorizedNetworksList := make([]interface{}, 0)
   922  					if vp != nil {
   923  						_authorizedNetworksList = vp.([]interface{})
   924  					}
   925  					_oipc_map := make(map[string]interface{})
   926  					for _, _ipc := range _oldAuthorizedNetworkList {
   927  						_entry := _ipc.(map[string]interface{})
   928  						_oipc_map[_entry["value"].(string)] = true
   929  					}
   930  					// Next read the network tuples from the server, and reinsert those that
   931  					// were not previously defined
   932  					for _, entry := range oldAuthorizedNetworks {
   933  						_, ok_old := _oipc_map[entry.Value]
   934  						if !ok_old {
   935  							settings.IpConfiguration.AuthorizedNetworks = append(
   936  								settings.IpConfiguration.AuthorizedNetworks, entry)
   937  						}
   938  					}
   939  					// finally, update old entries and insert new ones
   940  					// and are still defined.
   941  					for _, _ipc := range _authorizedNetworksList {
   942  						_entry := _ipc.(map[string]interface{})
   943  						entry := &sqladmin.AclEntry{}
   944  
   945  						if vpp, okpp := _entry["expiration_time"]; okpp {
   946  							entry.ExpirationTime = vpp.(string)
   947  						}
   948  
   949  						if vpp, okpp := _entry["name"]; okpp {
   950  							entry.Name = vpp.(string)
   951  						}
   952  
   953  						if vpp, okpp := _entry["value"]; okpp {
   954  							entry.Value = vpp.(string)
   955  						}
   956  
   957  						settings.IpConfiguration.AuthorizedNetworks = append(
   958  							settings.IpConfiguration.AuthorizedNetworks, entry)
   959  					}
   960  				}
   961  			}
   962  		}
   963  
   964  		if v, ok := _settings["location_preference"]; ok {
   965  			_locationPreferenceList := v.([]interface{})
   966  			if len(_locationPreferenceList) > 1 {
   967  				return fmt.Errorf("At most one location_preference block is allowed")
   968  			}
   969  
   970  			if len(_locationPreferenceList) == 1 && _locationPreferenceList[0] != nil {
   971  				settings.LocationPreference = &sqladmin.LocationPreference{}
   972  				_locationPreference := _locationPreferenceList[0].(map[string]interface{})
   973  
   974  				if vp, okp := _locationPreference["follow_gae_application"]; okp {
   975  					settings.LocationPreference.FollowGaeApplication = vp.(string)
   976  				}
   977  
   978  				if vp, okp := _locationPreference["zone"]; okp {
   979  					settings.LocationPreference.Zone = vp.(string)
   980  				}
   981  			}
   982  		}
   983  
   984  		if v, ok := _settings["pricing_plan"]; ok {
   985  			settings.PricingPlan = v.(string)
   986  		}
   987  
   988  		if v, ok := _settings["replication_type"]; ok {
   989  			settings.ReplicationType = v.(string)
   990  		}
   991  
   992  		instance.Settings = settings
   993  	}
   994  
   995  	d.Partial(false)
   996  
   997  	op, err := config.clientSqlAdmin.Instances.Update(project, instance.Name, instance).Do()
   998  	if err != nil {
   999  		return fmt.Errorf("Error, failed to update instance %s: %s", instance.Name, err)
  1000  	}
  1001  
  1002  	err = sqladminOperationWait(config, op, "Create Instance")
  1003  	if err != nil {
  1004  		return err
  1005  	}
  1006  
  1007  	return resourceSqlDatabaseInstanceRead(d, meta)
  1008  }
  1009  
  1010  func resourceSqlDatabaseInstanceDelete(d *schema.ResourceData, meta interface{}) error {
  1011  	config := meta.(*Config)
  1012  
  1013  	project, err := getProject(d, config)
  1014  	if err != nil {
  1015  		return err
  1016  	}
  1017  
  1018  	op, err := config.clientSqlAdmin.Instances.Delete(project, d.Get("name").(string)).Do()
  1019  
  1020  	if err != nil {
  1021  		return fmt.Errorf("Error, failed to delete instance %s: %s", d.Get("name").(string), err)
  1022  	}
  1023  
  1024  	err = sqladminOperationWait(config, op, "Delete Instance")
  1025  	if err != nil {
  1026  		return err
  1027  	}
  1028  
  1029  	return nil
  1030  }