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 }