github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/azure/resource_azure_sql_database_service.go (about)

     1  package azure
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/Azure/azure-sdk-for-go/management/sql"
    10  	"github.com/hashicorp/terraform/helper/schema"
    11  )
    12  
    13  // resourceAzureSqlDatabaseService returns the *schema.Resource
    14  // associated to an SQL Database Service on Azure.
    15  func resourceAzureSqlDatabaseService() *schema.Resource {
    16  	return &schema.Resource{
    17  		Create: resourceAzureSqlDatabaseServiceCreate,
    18  		Read:   resourceAzureSqlDatabaseServiceRead,
    19  		Update: resourceAzureSqlDatabaseServiceUpdate,
    20  		Exists: resourceAzureSqlDatabaseServiceExists,
    21  		Delete: resourceAzureSqlDatabaseServiceDelete,
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"name": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  			},
    28  			"database_server_name": &schema.Schema{
    29  				Type:     schema.TypeString,
    30  				Required: true,
    31  				ForceNew: true,
    32  			},
    33  			"collation": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Optional: true,
    36  				Computed: true,
    37  				ForceNew: true,
    38  			},
    39  			"edition": &schema.Schema{
    40  				Type:     schema.TypeString,
    41  				Optional: true,
    42  				Computed: true,
    43  			},
    44  			"max_size_bytes": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Optional: true,
    47  				Computed: true,
    48  			},
    49  			"service_level_id": &schema.Schema{
    50  				Type:     schema.TypeString,
    51  				Optional: true,
    52  				Computed: true,
    53  			},
    54  		},
    55  	}
    56  }
    57  
    58  // resourceAzureSqlDatabaseServiceCreate does all the necessary API calls to
    59  // create an SQL Database Service on Azure.
    60  func resourceAzureSqlDatabaseServiceCreate(d *schema.ResourceData, meta interface{}) error {
    61  	sqlClient := meta.(*Client).sqlClient
    62  
    63  	log.Println("[INFO] Creating Azure SQL Database service creation request.")
    64  	name := d.Get("name").(string)
    65  	serverName := d.Get("database_server_name").(string)
    66  	params := sql.DatabaseCreateParams{
    67  		Name:               name,
    68  		Edition:            d.Get("edition").(string),
    69  		CollationName:      d.Get("collation").(string),
    70  		ServiceObjectiveID: d.Get("service_level_id").(string),
    71  	}
    72  
    73  	if maxSize, ok := d.GetOk("max_size_bytes"); ok {
    74  		val, err := strconv.ParseInt(maxSize.(string), 10, 64)
    75  		if err != nil {
    76  			return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err)
    77  		}
    78  		params.MaxSizeBytes = val
    79  	}
    80  
    81  	log.Println("[INFO] Sending SQL Database Service creation request to Azure.")
    82  	err := sqlClient.CreateDatabase(serverName, params)
    83  	if err != nil {
    84  		return fmt.Errorf("Error issuing Azure SQL Database Service creation: %s", err)
    85  	}
    86  
    87  	log.Println("[INFO] Beginning wait for Azure SQL Database Service creation.")
    88  	err = sqlClient.WaitForDatabaseCreation(serverName, name, nil)
    89  	if err != nil {
    90  		return fmt.Errorf("Error whilst waiting for Azure SQL Database Service creation: %s", err)
    91  	}
    92  
    93  	d.SetId(name)
    94  
    95  	return resourceAzureSqlDatabaseServiceRead(d, meta)
    96  }
    97  
    98  // resourceAzureSqlDatabaseServiceRead does all the necessary API calls to
    99  // read the state of the SQL Database Service off Azure.
   100  func resourceAzureSqlDatabaseServiceRead(d *schema.ResourceData, meta interface{}) error {
   101  	sqlClient := meta.(*Client).sqlClient
   102  
   103  	log.Println("[INFO] Issuing Azure SQL Database Services list operation.")
   104  	serverName := d.Get("database_server_name").(string)
   105  	dbs, err := sqlClient.ListDatabases(serverName)
   106  	if err != nil {
   107  		return fmt.Errorf("Error whilst listing Database Services off Azure: %s", err)
   108  	}
   109  
   110  	// search for our database:
   111  	var found bool
   112  	name := d.Get("name").(string)
   113  	for _, db := range dbs.ServiceResources {
   114  		if db.Name == name {
   115  			found = true
   116  			d.Set("edition", db.Edition)
   117  			d.Set("collation", db.CollationName)
   118  			d.Set("max_size_bytes", strconv.FormatInt(db.MaxSizeBytes, 10))
   119  			d.Set("service_level_id", db.ServiceObjectiveID)
   120  			break
   121  		}
   122  	}
   123  
   124  	// if not found; we must untrack the resource:
   125  	if !found {
   126  		d.SetId("")
   127  	}
   128  
   129  	return nil
   130  }
   131  
   132  // resourceAzureSqlDatabaseServiceUpdate does all the necessary API calls to
   133  // update the state of the SQL Database Service off Azure.
   134  func resourceAzureSqlDatabaseServiceUpdate(d *schema.ResourceData, meta interface{}) error {
   135  	azureClient := meta.(*Client)
   136  	mgmtClient := azureClient.mgmtClient
   137  	sqlClient := azureClient.sqlClient
   138  	serverName := d.Get("database_server_name").(string)
   139  
   140  	// changes to the name must occur separately from changes to the attributes:
   141  	if d.HasChange("name") {
   142  		oldv, newv := d.GetChange("name")
   143  
   144  		// issue the update request:
   145  		log.Println("[INFO] Issuing Azure Database Service name change.")
   146  		reqID, err := sqlClient.UpdateDatabase(serverName, oldv.(string),
   147  			sql.ServiceResourceUpdateParams{
   148  				Name: newv.(string),
   149  			})
   150  
   151  		// wait for the update to occur:
   152  		log.Println("[INFO] Waiting for Azure SQL Database Service name change.")
   153  		err = mgmtClient.WaitForOperation(reqID, nil)
   154  		if err != nil {
   155  			return fmt.Errorf("Error waiting for Azure SQL Database Service name update: %s", err)
   156  		}
   157  
   158  		// set the new name as the ID:
   159  		d.SetId(newv.(string))
   160  	}
   161  
   162  	name := d.Get("name").(string)
   163  	cedition := d.HasChange("edition")
   164  	cmaxsize := d.HasChange("max_size_bytes")
   165  	clevel := d.HasChange("service_level_id")
   166  	if cedition || cmaxsize || clevel {
   167  		updateParams := sql.ServiceResourceUpdateParams{
   168  			// we still have to stick the name in here for good measure:
   169  			Name: name,
   170  		}
   171  
   172  		// build the update request:
   173  		if cedition {
   174  			updateParams.Edition = d.Get("edition").(string)
   175  		}
   176  		if maxSize, ok := d.GetOk("max_size_bytes"); cmaxsize && ok && maxSize.(string) != "" {
   177  			val, err := strconv.ParseInt(maxSize.(string), 10, 64)
   178  			if err != nil {
   179  				return fmt.Errorf("Provided max_size_bytes is not an integer: %s", err)
   180  			}
   181  			updateParams.MaxSizeBytes = val
   182  		}
   183  		if clevel {
   184  			updateParams.ServiceObjectiveID = d.Get("service_level_id").(string)
   185  		}
   186  
   187  		// issue the update:
   188  		log.Println("[INFO] Issuing Azure Database Service parameter update.")
   189  		reqID, err := sqlClient.UpdateDatabase(serverName, name, updateParams)
   190  		if err != nil {
   191  			return fmt.Errorf("Failed issuing Azure SQL Service parameter update: %s", err)
   192  		}
   193  
   194  		log.Println("[INFO] Waiting for Azure SQL Database Service parameter update.")
   195  		err = mgmtClient.WaitForOperation(reqID, nil)
   196  		if err != nil {
   197  			return fmt.Errorf("Error waiting for Azure SQL Database Service parameter update: %s", err)
   198  		}
   199  	}
   200  
   201  	return nil
   202  }
   203  
   204  // resourceAzureSqlDatabaseServiceExists does all the necessary API calls to
   205  // check for the existence of the SQL Database Service off Azure.
   206  func resourceAzureSqlDatabaseServiceExists(d *schema.ResourceData, meta interface{}) (bool, error) {
   207  	sqlClient := meta.(*Client).sqlClient
   208  
   209  	log.Println("[INFO] Issuing Azure SQL Database Service get request.")
   210  	name := d.Get("name").(string)
   211  	serverName := d.Get("database_server_name").(string)
   212  	_, err := sqlClient.GetDatabase(serverName, name)
   213  	if err != nil {
   214  		if strings.Contains(err.Error(), "does not exist") {
   215  			d.SetId("")
   216  			return false, nil
   217  		} else {
   218  			return false, fmt.Errorf("Error whilst getting Azure SQL Database Service info: %s", err)
   219  		}
   220  	}
   221  
   222  	return true, nil
   223  }
   224  
   225  // resourceAzureSqlDatabaseServiceDelete does all the necessary API calls to
   226  // delete the SQL Database Service off Azure.
   227  func resourceAzureSqlDatabaseServiceDelete(d *schema.ResourceData, meta interface{}) error {
   228  	sqlClient := meta.(*Client).sqlClient
   229  
   230  	log.Println("[INFO] Issuing Azure SQL Database deletion request.")
   231  	name := d.Get("name").(string)
   232  	serverName := d.Get("database_server_name").(string)
   233  	return sqlClient.DeleteDatabase(serverName, name)
   234  }