github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/provider/azure/config.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package azure 5 6 import ( 7 "fmt" 8 "io/ioutil" 9 10 "github.com/juju/schema" 11 12 "github.com/juju/juju/environs/config" 13 ) 14 15 var configFields = schema.Fields{ 16 "location": schema.String(), 17 "management-subscription-id": schema.String(), 18 "management-certificate-path": schema.String(), 19 "management-certificate": schema.String(), 20 "storage-account-name": schema.String(), 21 "force-image-name": schema.String(), 22 "availability-sets-enabled": schema.Bool(), 23 } 24 var configDefaults = schema.Defaults{ 25 "location": "", 26 "management-certificate": "", 27 "management-certificate-path": "", 28 "force-image-name": "", 29 // availability-sets-enabled is set to Omit (equivalent 30 // to false) for backwards compatibility. 31 "availability-sets-enabled": schema.Omit, 32 } 33 34 type azureEnvironConfig struct { 35 *config.Config 36 attrs map[string]interface{} 37 } 38 39 func (cfg *azureEnvironConfig) location() string { 40 return cfg.attrs["location"].(string) 41 } 42 43 func (cfg *azureEnvironConfig) managementSubscriptionId() string { 44 return cfg.attrs["management-subscription-id"].(string) 45 } 46 47 func (cfg *azureEnvironConfig) managementCertificate() string { 48 return cfg.attrs["management-certificate"].(string) 49 } 50 51 func (cfg *azureEnvironConfig) storageAccountName() string { 52 return cfg.attrs["storage-account-name"].(string) 53 } 54 55 func (cfg *azureEnvironConfig) forceImageName() string { 56 return cfg.attrs["force-image-name"].(string) 57 } 58 59 func (cfg *azureEnvironConfig) availabilitySetsEnabled() bool { 60 enabled, _ := cfg.attrs["availability-sets-enabled"].(bool) 61 return enabled 62 } 63 64 func (prov azureEnvironProvider) newConfig(cfg *config.Config) (*azureEnvironConfig, error) { 65 validCfg, err := prov.Validate(cfg, nil) 66 if err != nil { 67 return nil, err 68 } 69 result := new(azureEnvironConfig) 70 result.Config = validCfg 71 result.attrs = validCfg.UnknownAttrs() 72 return result, nil 73 } 74 75 // Validate ensures that config is a valid configuration for this 76 // provider like specified in the EnvironProvider interface. 77 func (prov azureEnvironProvider) Validate(cfg, oldCfg *config.Config) (*config.Config, error) { 78 // Validate base configuration change before validating Azure specifics. 79 err := config.Validate(cfg, oldCfg) 80 if err != nil { 81 return nil, err 82 } 83 84 // User cannot change availability-sets-enabled after environment is prepared. 85 if oldCfg != nil { 86 if oldCfg.AllAttrs()["availability-sets-enabled"] != cfg.AllAttrs()["availability-sets-enabled"] { 87 return nil, fmt.Errorf("cannot change availability-sets-enabled") 88 } 89 } 90 91 validated, err := cfg.ValidateUnknownAttrs(configFields, configDefaults) 92 if err != nil { 93 return nil, err 94 } 95 envCfg := new(azureEnvironConfig) 96 envCfg.Config = cfg 97 envCfg.attrs = validated 98 99 cert := envCfg.managementCertificate() 100 if cert == "" { 101 certPath := envCfg.attrs["management-certificate-path"].(string) 102 pemData, err := ioutil.ReadFile(certPath) 103 if err != nil { 104 return nil, fmt.Errorf("invalid management-certificate-path: %s", err) 105 } 106 envCfg.attrs["management-certificate"] = string(pemData) 107 } 108 delete(envCfg.attrs, "management-certificate-path") 109 if envCfg.location() == "" { 110 return nil, fmt.Errorf("environment has no location; you need to set one. E.g. 'West US'") 111 } 112 return cfg.Apply(envCfg.attrs) 113 } 114 115 var boilerplateYAML = ` 116 # https://juju.ubuntu.com/docs/config-azure.html 117 azure: 118 type: azure 119 120 # location specifies the place where instances will be started, 121 # for example: West US, North Europe. 122 # 123 location: West US 124 125 # The following attributes specify Windows Azure Management 126 # information. See: 127 # http://msdn.microsoft.com/en-us/library/windowsazure 128 # for details. 129 # 130 management-subscription-id: <00000000-0000-0000-0000-000000000000> 131 management-certificate-path: /home/me/azure.pem 132 133 # storage-account-name holds Windows Azure Storage info. 134 # 135 storage-account-name: abcdefghijkl 136 137 # force-image-name overrides the OS image selection to use a fixed 138 # image for all deployments. Most useful for developers. 139 # 140 # force-image-name: b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-13_10-amd64-server-DEVELOPMENT-20130713-Juju_ALPHA-en-us-30GB 141 142 # image-stream chooses a simplestreams stream to select OS images 143 # from, for example daily or released images (or any other stream 144 # available on simplestreams). 145 # 146 # image-stream: "released" 147 148 `[1:] 149 150 func (prov azureEnvironProvider) BoilerplateConfig() string { 151 return boilerplateYAML 152 } 153 154 // SecretAttrs is specified in the EnvironProvider interface. 155 func (prov azureEnvironProvider) SecretAttrs(cfg *config.Config) (map[string]string, error) { 156 secretAttrs := make(map[string]string) 157 azureCfg, err := prov.newConfig(cfg) 158 if err != nil { 159 return nil, err 160 } 161 secretAttrs["management-certificate"] = azureCfg.managementCertificate() 162 return secretAttrs, nil 163 }