github.com/anuaimi/terraform@v0.6.4-0.20150904235404-2bf9aec61da8/builtin/providers/azure/provider.go (about)

     1  package azure
     2  
     3  import (
     4  	"encoding/xml"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  
     9  	"github.com/hashicorp/terraform/helper/schema"
    10  	"github.com/hashicorp/terraform/terraform"
    11  	"github.com/mitchellh/go-homedir"
    12  )
    13  
    14  // Provider returns a terraform.ResourceProvider.
    15  func Provider() terraform.ResourceProvider {
    16  	return &schema.Provider{
    17  		Schema: map[string]*schema.Schema{
    18  			"settings_file": &schema.Schema{
    19  				Type:         schema.TypeString,
    20  				Optional:     true,
    21  				DefaultFunc:  schema.EnvDefaultFunc("AZURE_SETTINGS_FILE", nil),
    22  				ValidateFunc: validateSettingsFile,
    23  			},
    24  
    25  			"subscription_id": &schema.Schema{
    26  				Type:        schema.TypeString,
    27  				Optional:    true,
    28  				DefaultFunc: schema.EnvDefaultFunc("AZURE_SUBSCRIPTION_ID", ""),
    29  			},
    30  
    31  			"certificate": &schema.Schema{
    32  				Type:        schema.TypeString,
    33  				Optional:    true,
    34  				DefaultFunc: schema.EnvDefaultFunc("AZURE_CERTIFICATE", ""),
    35  			},
    36  		},
    37  
    38  		ResourcesMap: map[string]*schema.Resource{
    39  			"azure_instance":                          resourceAzureInstance(),
    40  			"azure_affinity_group":                    resourceAzureAffinityGroup(),
    41  			"azure_data_disk":                         resourceAzureDataDisk(),
    42  			"azure_sql_database_server":               resourceAzureSqlDatabaseServer(),
    43  			"azure_sql_database_server_firewall_rule": resourceAzureSqlDatabaseServerFirewallRule(),
    44  			"azure_sql_database_service":              resourceAzureSqlDatabaseService(),
    45  			"azure_hosted_service":                    resourceAzureHostedService(),
    46  			"azure_storage_service":                   resourceAzureStorageService(),
    47  			"azure_storage_container":                 resourceAzureStorageContainer(),
    48  			"azure_storage_blob":                      resourceAzureStorageBlob(),
    49  			"azure_storage_queue":                     resourceAzureStorageQueue(),
    50  			"azure_virtual_network":                   resourceAzureVirtualNetwork(),
    51  			"azure_dns_server":                        resourceAzureDnsServer(),
    52  			"azure_local_network_connection":          resourceAzureLocalNetworkConnection(),
    53  			"azure_security_group":                    resourceAzureSecurityGroup(),
    54  			"azure_security_group_rule":               resourceAzureSecurityGroupRule(),
    55  		},
    56  
    57  		ConfigureFunc: providerConfigure,
    58  	}
    59  }
    60  
    61  func providerConfigure(d *schema.ResourceData) (interface{}, error) {
    62  	config := Config{
    63  		SubscriptionID: d.Get("subscription_id").(string),
    64  		Certificate:    []byte(d.Get("certificate").(string)),
    65  	}
    66  
    67  	settings := d.Get("settings_file").(string)
    68  
    69  	if settings != "" {
    70  		if ok, _ := isFile(settings); ok {
    71  			settingsFile, err := homedir.Expand(settings)
    72  			if err != nil {
    73  				return nil, fmt.Errorf("Error expanding the settings file path: %s", err)
    74  			}
    75  			publishSettingsContent, err := ioutil.ReadFile(settingsFile)
    76  			if err != nil {
    77  				return nil, fmt.Errorf("Error reading settings file: %s", err)
    78  			}
    79  			config.Settings = publishSettingsContent
    80  		} else {
    81  			config.Settings = []byte(settings)
    82  		}
    83  		return config.NewClientFromSettingsData()
    84  	}
    85  
    86  	if config.SubscriptionID != "" && len(config.Certificate) > 0 {
    87  		return config.NewClient()
    88  	}
    89  
    90  	return nil, fmt.Errorf(
    91  		"Insufficient configuration data. Please specify either a 'settings_file'\n" +
    92  			"or both a 'subscription_id' and 'certificate'.")
    93  }
    94  
    95  func validateSettingsFile(v interface{}, k string) (warnings []string, errors []error) {
    96  	value := v.(string)
    97  
    98  	if value == "" {
    99  		return
   100  	}
   101  
   102  	var settings settingsData
   103  	if err := xml.Unmarshal([]byte(value), &settings); err != nil {
   104  		warnings = append(warnings, `
   105  settings_file is not valid XML, so we are assuming it is a file path. This
   106  support will be removed in the future. Please update your configuration to use
   107  ${file("filename.publishsettings")} instead.`)
   108  	} else {
   109  		return
   110  	}
   111  
   112  	if ok, err := isFile(value); !ok {
   113  		errors = append(errors,
   114  			fmt.Errorf(
   115  				"account_file path could not be read from '%s': %s",
   116  				value,
   117  				err))
   118  	}
   119  
   120  	return
   121  }
   122  
   123  func isFile(v string) (bool, error) {
   124  	if _, err := os.Stat(v); err != nil {
   125  		return false, err
   126  	}
   127  	return true, nil
   128  }
   129  
   130  // settingsData is a private struct used to test the unmarshalling of the
   131  // settingsFile contents, to determine if the contents are valid XML
   132  type settingsData struct {
   133  	XMLName xml.Name `xml:"PublishData"`
   134  }