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