228 lines
7.0 KiB
Go
228 lines
7.0 KiB
Go
package azure
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"log"
|
|
|
|
"github.com/Azure/azure-sdk-for-go/management"
|
|
"github.com/Azure/azure-sdk-for-go/management/storageservice"
|
|
"github.com/hashicorp/terraform/helper/schema"
|
|
)
|
|
|
|
// resourceAzureStorageService returns the *schema.Resource associated
|
|
// to an Azure hosted service.
|
|
func resourceAzureStorageService() *schema.Resource {
|
|
return &schema.Resource{
|
|
Create: resourceAzureStorageServiceCreate,
|
|
Read: resourceAzureStorageServiceRead,
|
|
Exists: resourceAzureStorageServiceExists,
|
|
Delete: resourceAzureStorageServiceDelete,
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
// General attributes:
|
|
"name": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
// TODO(aznashwan): constrain name in description
|
|
Description: parameterDescriptions["name"],
|
|
},
|
|
"location": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
Description: parameterDescriptions["location"],
|
|
},
|
|
"label": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
Default: "Made by Terraform.",
|
|
Description: parameterDescriptions["label"],
|
|
},
|
|
"description": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
Description: parameterDescriptions["description"],
|
|
},
|
|
// Functional attributes:
|
|
"account_type": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Required: true,
|
|
ForceNew: true,
|
|
Description: parameterDescriptions["account_type"],
|
|
},
|
|
"affinity_group": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
Description: parameterDescriptions["affinity_group"],
|
|
},
|
|
"properties": &schema.Schema{
|
|
Type: schema.TypeMap,
|
|
Optional: true,
|
|
ForceNew: true,
|
|
Elem: schema.TypeString,
|
|
},
|
|
// Computed attributes:
|
|
"url": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"primary_key": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
"secondary_key": &schema.Schema{
|
|
Type: schema.TypeString,
|
|
Computed: true,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// resourceAzureStorageServiceCreate does all the necessary API calls to
|
|
// create a new Azure storage service.
|
|
func resourceAzureStorageServiceCreate(d *schema.ResourceData, meta interface{}) error {
|
|
azureClient := meta.(*Client)
|
|
mgmtClient := azureClient.mgmtClient
|
|
storageServiceClient := storageservice.NewClient(mgmtClient)
|
|
|
|
// get all the values:
|
|
log.Println("[INFO] Creating Azure Storage Service creation parameters.")
|
|
name := d.Get("name").(string)
|
|
location := d.Get("location").(string)
|
|
accountType := storageservice.AccountType(d.Get("account_type").(string))
|
|
affinityGroup := d.Get("affinity_group").(string)
|
|
description := d.Get("description").(string)
|
|
label := base64.StdEncoding.EncodeToString([]byte(d.Get("label").(string)))
|
|
var props []storageservice.ExtendedProperty
|
|
if given := d.Get("properties").(map[string]interface{}); len(given) > 0 {
|
|
props = []storageservice.ExtendedProperty{}
|
|
for k, v := range given {
|
|
props = append(props, storageservice.ExtendedProperty{
|
|
Name: k,
|
|
Value: v.(string),
|
|
})
|
|
}
|
|
}
|
|
|
|
// create parameters and send request:
|
|
log.Println("[INFO] Sending Storage Service creation request to Azure.")
|
|
reqID, err := storageServiceClient.CreateStorageService(
|
|
storageservice.StorageAccountCreateParameters{
|
|
ServiceName: name,
|
|
Location: location,
|
|
Description: description,
|
|
Label: label,
|
|
AffinityGroup: affinityGroup,
|
|
AccountType: accountType,
|
|
ExtendedProperties: storageservice.ExtendedPropertyList{
|
|
ExtendedProperty: props,
|
|
},
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("Failed to create Azure storage service %s: %s", name, err)
|
|
}
|
|
err = mgmtClient.WaitForOperation(reqID, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed creating storage service %s: %s", name, err)
|
|
}
|
|
|
|
d.SetId(name)
|
|
return resourceAzureStorageServiceRead(d, meta)
|
|
}
|
|
|
|
// resourceAzureStorageServiceRead does all the necessary API calls to
|
|
// read the state of the storage service off Azure.
|
|
func resourceAzureStorageServiceRead(d *schema.ResourceData, meta interface{}) error {
|
|
azureClient := meta.(*Client)
|
|
mgmtClient := azureClient.mgmtClient
|
|
storageServiceClient := storageservice.NewClient(mgmtClient)
|
|
|
|
// get our storage service:
|
|
log.Println("[INFO] Sending query about storage service to Azure.")
|
|
name := d.Get("name").(string)
|
|
storsvc, err := storageServiceClient.GetStorageService(name)
|
|
if err != nil {
|
|
if !management.IsResourceNotFoundError(err) {
|
|
return fmt.Errorf("Failed to query about Azure about storage service: %s", err)
|
|
} else {
|
|
// it means that the resource has been deleted from Azure
|
|
// in the meantime and we must remove its associated Resource.
|
|
d.SetId("")
|
|
return nil
|
|
|
|
}
|
|
}
|
|
|
|
// read values:
|
|
d.Set("url", storsvc.URL)
|
|
log.Println("[INFO] Querying keys of Azure storage service.")
|
|
keys, err := storageServiceClient.GetStorageServiceKeys(name)
|
|
if err != nil {
|
|
return fmt.Errorf("Failed querying keys for Azure storage service: %s", err)
|
|
}
|
|
d.Set("primary_key", keys.PrimaryKey)
|
|
d.Set("secondary_key", keys.SecondaryKey)
|
|
|
|
return nil
|
|
}
|
|
|
|
// resourceAzureStorageServiceExists does all the necessary API calls to
|
|
// check if the storage service exists on Azure.
|
|
func resourceAzureStorageServiceExists(d *schema.ResourceData, meta interface{}) (bool, error) {
|
|
azureClient, ok := meta.(*Client)
|
|
if !ok {
|
|
return false, fmt.Errorf("Failed to convert to *Client, got: %T", meta)
|
|
}
|
|
mgmtClient := azureClient.mgmtClient
|
|
storageServiceClient := storageservice.NewClient(mgmtClient)
|
|
|
|
// get our storage service:
|
|
log.Println("[INFO] Sending query about storage service to Azure.")
|
|
name := d.Get("name").(string)
|
|
_, err := storageServiceClient.GetStorageService(name)
|
|
if err != nil {
|
|
if !management.IsResourceNotFoundError(err) {
|
|
return false, fmt.Errorf("Failed to query about Azure about storage service: %s", err)
|
|
} else {
|
|
// it means that the resource has been deleted from Azure
|
|
// in the meantime and we must remove its associated Resource.
|
|
d.SetId("")
|
|
return false, nil
|
|
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// resourceAzureStorageServiceDelete does all the necessary API calls to
|
|
// delete the storage service off Azure.
|
|
func resourceAzureStorageServiceDelete(d *schema.ResourceData, meta interface{}) error {
|
|
azureClient, ok := meta.(*Client)
|
|
if !ok {
|
|
return fmt.Errorf("Failed to convert to *Client, got: %T", meta)
|
|
}
|
|
mgmtClient := azureClient.mgmtClient
|
|
storageClient := storageservice.NewClient(mgmtClient)
|
|
|
|
// issue the deletion:
|
|
name := d.Get("name").(string)
|
|
log.Println("[INFO] Issuing delete of storage service off Azure.")
|
|
reqID, err := storageClient.DeleteStorageService(name)
|
|
if err != nil {
|
|
return fmt.Errorf("Error whilst issuing deletion of storage service off Azure: %s", err)
|
|
}
|
|
err = mgmtClient.WaitForOperation(reqID, nil)
|
|
if err != nil {
|
|
return fmt.Errorf("Error whilst deleting storage service off Azure: %s", err)
|
|
}
|
|
|
|
d.SetId("")
|
|
return nil
|
|
}
|