10 "github.com/Azure/go-autorest/autorest"
13 // Copyright 2017 Microsoft Corporation
15 // Licensed under the Apache License, Version 2.0 (the "License");
16 // you may not use this file except in compliance with the License.
17 // You may obtain a copy of the License at
19 // http://www.apache.org/licenses/LICENSE-2.0
21 // Unless required by applicable law or agreed to in writing, software
22 // distributed under the License is distributed on an "AS IS" BASIS,
23 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 // See the License for the specific language governing permissions and
25 // limitations under the License.
27 type audience []string
29 type authentication struct {
30 LoginEndpoint string `json:"loginEndpoint"`
31 Audiences audience `json:"audiences"`
34 type environmentMetadataInfo struct {
35 GalleryEndpoint string `json:"galleryEndpoint"`
36 GraphEndpoint string `json:"graphEndpoint"`
37 PortalEndpoint string `json:"portalEndpoint"`
38 Authentication authentication `json:"authentication"`
41 // EnvironmentProperty represent property names that clients can override
42 type EnvironmentProperty string
45 // EnvironmentName ...
46 EnvironmentName EnvironmentProperty = "name"
47 // EnvironmentManagementPortalURL ..
48 EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL"
49 // EnvironmentPublishSettingsURL ...
50 EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL"
51 // EnvironmentServiceManagementEndpoint ...
52 EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint"
53 // EnvironmentResourceManagerEndpoint ...
54 EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint"
55 // EnvironmentActiveDirectoryEndpoint ...
56 EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint"
57 // EnvironmentGalleryEndpoint ...
58 EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint"
59 // EnvironmentKeyVaultEndpoint ...
60 EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint"
61 // EnvironmentGraphEndpoint ...
62 EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint"
63 // EnvironmentServiceBusEndpoint ...
64 EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint"
65 // EnvironmentBatchManagementEndpoint ...
66 EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint"
67 // EnvironmentStorageEndpointSuffix ...
68 EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix"
69 // EnvironmentSQLDatabaseDNSSuffix ...
70 EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix"
71 // EnvironmentTrafficManagerDNSSuffix ...
72 EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix"
73 // EnvironmentKeyVaultDNSSuffix ...
74 EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix"
75 // EnvironmentServiceBusEndpointSuffix ...
76 EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix"
77 // EnvironmentServiceManagementVMDNSSuffix ...
78 EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix"
79 // EnvironmentResourceManagerVMDNSSuffix ...
80 EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix"
81 // EnvironmentContainerRegistryDNSSuffix ...
82 EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix"
83 // EnvironmentTokenAudience ...
84 EnvironmentTokenAudience EnvironmentProperty = "tokenAudience"
87 // OverrideProperty represents property name and value that clients can override
88 type OverrideProperty struct {
89 Key EnvironmentProperty
93 // EnvironmentFromURL loads an Environment from a URL
94 // This function is particularly useful in the Hybrid Cloud model, where one may define their own
96 func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) {
97 var metadataEnvProperties environmentMetadataInfo
99 if resourceManagerEndpoint == "" {
100 return environment, fmt.Errorf("Metadata resource manager endpoint is empty")
103 if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil {
104 return environment, err
107 // Give priority to user's override values
108 overrideProperties(&environment, properties)
110 if environment.Name == "" {
111 environment.Name = "HybridEnvironment"
113 stampDNSSuffix := environment.StorageEndpointSuffix
114 if stampDNSSuffix == "" {
115 stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/")
116 environment.StorageEndpointSuffix = stampDNSSuffix
118 if environment.KeyVaultDNSSuffix == "" {
119 environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix)
121 if environment.KeyVaultEndpoint == "" {
122 environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix)
124 if environment.TokenAudience == "" {
125 environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0]
127 if environment.ActiveDirectoryEndpoint == "" {
128 environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint
130 if environment.ResourceManagerEndpoint == "" {
131 environment.ResourceManagerEndpoint = resourceManagerEndpoint
133 if environment.GalleryEndpoint == "" {
134 environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint
136 if environment.GraphEndpoint == "" {
137 environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint
140 return environment, nil
143 func overrideProperties(environment *Environment, properties []OverrideProperty) {
144 for _, property := range properties {
145 switch property.Key {
146 case EnvironmentName:
148 environment.Name = property.Value
150 case EnvironmentManagementPortalURL:
152 environment.ManagementPortalURL = property.Value
154 case EnvironmentPublishSettingsURL:
156 environment.PublishSettingsURL = property.Value
158 case EnvironmentServiceManagementEndpoint:
160 environment.ServiceManagementEndpoint = property.Value
162 case EnvironmentResourceManagerEndpoint:
164 environment.ResourceManagerEndpoint = property.Value
166 case EnvironmentActiveDirectoryEndpoint:
168 environment.ActiveDirectoryEndpoint = property.Value
170 case EnvironmentGalleryEndpoint:
172 environment.GalleryEndpoint = property.Value
174 case EnvironmentKeyVaultEndpoint:
176 environment.KeyVaultEndpoint = property.Value
178 case EnvironmentGraphEndpoint:
180 environment.GraphEndpoint = property.Value
182 case EnvironmentServiceBusEndpoint:
184 environment.ServiceBusEndpoint = property.Value
186 case EnvironmentBatchManagementEndpoint:
188 environment.BatchManagementEndpoint = property.Value
190 case EnvironmentStorageEndpointSuffix:
192 environment.StorageEndpointSuffix = property.Value
194 case EnvironmentSQLDatabaseDNSSuffix:
196 environment.SQLDatabaseDNSSuffix = property.Value
198 case EnvironmentTrafficManagerDNSSuffix:
200 environment.TrafficManagerDNSSuffix = property.Value
202 case EnvironmentKeyVaultDNSSuffix:
204 environment.KeyVaultDNSSuffix = property.Value
206 case EnvironmentServiceBusEndpointSuffix:
208 environment.ServiceBusEndpointSuffix = property.Value
210 case EnvironmentServiceManagementVMDNSSuffix:
212 environment.ServiceManagementVMDNSSuffix = property.Value
214 case EnvironmentResourceManagerVMDNSSuffix:
216 environment.ResourceManagerVMDNSSuffix = property.Value
218 case EnvironmentContainerRegistryDNSSuffix:
220 environment.ContainerRegistryDNSSuffix = property.Value
222 case EnvironmentTokenAudience:
224 environment.TokenAudience = property.Value
230 func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) {
231 client := autorest.NewClientWithUserAgent("")
232 managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0")
233 req, _ := http.NewRequest("GET", managementEndpoint, nil)
234 response, err := client.Do(req)
236 return environment, err
238 defer response.Body.Close()
239 jsonResponse, err := ioutil.ReadAll(response.Body)
241 return environment, err
243 err = json.Unmarshal(jsonResponse, &environment)
244 return environment, err