github.com/mohanarpit/terraform@v0.6.16-0.20160909104007-291f29853544/builtin/providers/google/resource_sql_database_instance.go (about)

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