1package azure
2
3// Copyright 2017 Microsoft Corporation
4//
5//  Licensed under the Apache License, Version 2.0 (the "License");
6//  you may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at
8//
9//      http://www.apache.org/licenses/LICENSE-2.0
10//
11//  Unless required by applicable law or agreed to in writing, software
12//  distributed under the License is distributed on an "AS IS" BASIS,
13//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14//  See the License for the specific language governing permissions and
15//  limitations under the License.
16
17import (
18	"encoding/json"
19	"fmt"
20	"io/ioutil"
21	"os"
22	"strings"
23)
24
25const (
26	// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
27	// to be used while populating the Azure Environment.
28	EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
29
30	// NotAvailable is used for endpoints and resource IDs that are not available for a given cloud.
31	NotAvailable = "N/A"
32)
33
34var environments = map[string]Environment{
35	"AZURECHINACLOUD":        ChinaCloud,
36	"AZUREGERMANCLOUD":       GermanCloud,
37	"AZUREPUBLICCLOUD":       PublicCloud,
38	"AZUREUSGOVERNMENTCLOUD": USGovernmentCloud,
39}
40
41// ResourceIdentifier contains a set of Azure resource IDs.
42type ResourceIdentifier struct {
43	Graph               string `json:"graph"`
44	KeyVault            string `json:"keyVault"`
45	Datalake            string `json:"datalake"`
46	Batch               string `json:"batch"`
47	OperationalInsights string `json:"operationalInsights"`
48	Storage             string `json:"storage"`
49	Synapse             string `json:"synapse"`
50	ServiceBus          string `json:"serviceBus"`
51}
52
53// Environment represents a set of endpoints for each of Azure's Clouds.
54type Environment struct {
55	Name                         string             `json:"name"`
56	ManagementPortalURL          string             `json:"managementPortalURL"`
57	PublishSettingsURL           string             `json:"publishSettingsURL"`
58	ServiceManagementEndpoint    string             `json:"serviceManagementEndpoint"`
59	ResourceManagerEndpoint      string             `json:"resourceManagerEndpoint"`
60	ActiveDirectoryEndpoint      string             `json:"activeDirectoryEndpoint"`
61	GalleryEndpoint              string             `json:"galleryEndpoint"`
62	KeyVaultEndpoint             string             `json:"keyVaultEndpoint"`
63	GraphEndpoint                string             `json:"graphEndpoint"`
64	ServiceBusEndpoint           string             `json:"serviceBusEndpoint"`
65	BatchManagementEndpoint      string             `json:"batchManagementEndpoint"`
66	StorageEndpointSuffix        string             `json:"storageEndpointSuffix"`
67	SQLDatabaseDNSSuffix         string             `json:"sqlDatabaseDNSSuffix"`
68	TrafficManagerDNSSuffix      string             `json:"trafficManagerDNSSuffix"`
69	KeyVaultDNSSuffix            string             `json:"keyVaultDNSSuffix"`
70	ServiceBusEndpointSuffix     string             `json:"serviceBusEndpointSuffix"`
71	ServiceManagementVMDNSSuffix string             `json:"serviceManagementVMDNSSuffix"`
72	ResourceManagerVMDNSSuffix   string             `json:"resourceManagerVMDNSSuffix"`
73	ContainerRegistryDNSSuffix   string             `json:"containerRegistryDNSSuffix"`
74	CosmosDBDNSSuffix            string             `json:"cosmosDBDNSSuffix"`
75	TokenAudience                string             `json:"tokenAudience"`
76	APIManagementHostNameSuffix  string             `json:"apiManagementHostNameSuffix"`
77	SynapseEndpointSuffix        string             `json:"synapseEndpointSuffix"`
78	ResourceIdentifiers          ResourceIdentifier `json:"resourceIdentifiers"`
79}
80
81var (
82	// PublicCloud is the default public Azure cloud environment
83	PublicCloud = Environment{
84		Name:                         "AzurePublicCloud",
85		ManagementPortalURL:          "https://manage.windowsazure.com/",
86		PublishSettingsURL:           "https://manage.windowsazure.com/publishsettings/index",
87		ServiceManagementEndpoint:    "https://management.core.windows.net/",
88		ResourceManagerEndpoint:      "https://management.azure.com/",
89		ActiveDirectoryEndpoint:      "https://login.microsoftonline.com/",
90		GalleryEndpoint:              "https://gallery.azure.com/",
91		KeyVaultEndpoint:             "https://vault.azure.net/",
92		GraphEndpoint:                "https://graph.windows.net/",
93		ServiceBusEndpoint:           "https://servicebus.windows.net/",
94		BatchManagementEndpoint:      "https://batch.core.windows.net/",
95		StorageEndpointSuffix:        "core.windows.net",
96		SQLDatabaseDNSSuffix:         "database.windows.net",
97		TrafficManagerDNSSuffix:      "trafficmanager.net",
98		KeyVaultDNSSuffix:            "vault.azure.net",
99		ServiceBusEndpointSuffix:     "servicebus.windows.net",
100		ServiceManagementVMDNSSuffix: "cloudapp.net",
101		ResourceManagerVMDNSSuffix:   "cloudapp.azure.com",
102		ContainerRegistryDNSSuffix:   "azurecr.io",
103		CosmosDBDNSSuffix:            "documents.azure.com",
104		TokenAudience:                "https://management.azure.com/",
105		APIManagementHostNameSuffix:  "azure-api.net",
106		SynapseEndpointSuffix:        "dev.azuresynapse.net",
107		ResourceIdentifiers: ResourceIdentifier{
108			Graph:               "https://graph.windows.net/",
109			KeyVault:            "https://vault.azure.net",
110			Datalake:            "https://datalake.azure.net/",
111			Batch:               "https://batch.core.windows.net/",
112			OperationalInsights: "https://api.loganalytics.io",
113			Storage:             "https://storage.azure.com/",
114			Synapse:             "https://dev.azuresynapse.net",
115			ServiceBus:          "https://servicebus.azure.net/",
116		},
117	}
118
119	// USGovernmentCloud is the cloud environment for the US Government
120	USGovernmentCloud = Environment{
121		Name:                         "AzureUSGovernmentCloud",
122		ManagementPortalURL:          "https://manage.windowsazure.us/",
123		PublishSettingsURL:           "https://manage.windowsazure.us/publishsettings/index",
124		ServiceManagementEndpoint:    "https://management.core.usgovcloudapi.net/",
125		ResourceManagerEndpoint:      "https://management.usgovcloudapi.net/",
126		ActiveDirectoryEndpoint:      "https://login.microsoftonline.us/",
127		GalleryEndpoint:              "https://gallery.usgovcloudapi.net/",
128		KeyVaultEndpoint:             "https://vault.usgovcloudapi.net/",
129		GraphEndpoint:                "https://graph.windows.net/",
130		ServiceBusEndpoint:           "https://servicebus.usgovcloudapi.net/",
131		BatchManagementEndpoint:      "https://batch.core.usgovcloudapi.net/",
132		StorageEndpointSuffix:        "core.usgovcloudapi.net",
133		SQLDatabaseDNSSuffix:         "database.usgovcloudapi.net",
134		TrafficManagerDNSSuffix:      "usgovtrafficmanager.net",
135		KeyVaultDNSSuffix:            "vault.usgovcloudapi.net",
136		ServiceBusEndpointSuffix:     "servicebus.usgovcloudapi.net",
137		ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
138		ResourceManagerVMDNSSuffix:   "cloudapp.usgovcloudapi.net",
139		ContainerRegistryDNSSuffix:   "azurecr.us",
140		CosmosDBDNSSuffix:            "documents.azure.us",
141		TokenAudience:                "https://management.usgovcloudapi.net/",
142		APIManagementHostNameSuffix:  "azure-api.us",
143		SynapseEndpointSuffix:        NotAvailable,
144		ResourceIdentifiers: ResourceIdentifier{
145			Graph:               "https://graph.windows.net/",
146			KeyVault:            "https://vault.usgovcloudapi.net",
147			Datalake:            NotAvailable,
148			Batch:               "https://batch.core.usgovcloudapi.net/",
149			OperationalInsights: "https://api.loganalytics.us",
150			Storage:             "https://storage.azure.com/",
151			Synapse:             NotAvailable,
152			ServiceBus:          "https://servicebus.azure.net/",
153		},
154	}
155
156	// ChinaCloud is the cloud environment operated in China
157	ChinaCloud = Environment{
158		Name:                         "AzureChinaCloud",
159		ManagementPortalURL:          "https://manage.chinacloudapi.com/",
160		PublishSettingsURL:           "https://manage.chinacloudapi.com/publishsettings/index",
161		ServiceManagementEndpoint:    "https://management.core.chinacloudapi.cn/",
162		ResourceManagerEndpoint:      "https://management.chinacloudapi.cn/",
163		ActiveDirectoryEndpoint:      "https://login.chinacloudapi.cn/",
164		GalleryEndpoint:              "https://gallery.chinacloudapi.cn/",
165		KeyVaultEndpoint:             "https://vault.azure.cn/",
166		GraphEndpoint:                "https://graph.chinacloudapi.cn/",
167		ServiceBusEndpoint:           "https://servicebus.chinacloudapi.cn/",
168		BatchManagementEndpoint:      "https://batch.chinacloudapi.cn/",
169		StorageEndpointSuffix:        "core.chinacloudapi.cn",
170		SQLDatabaseDNSSuffix:         "database.chinacloudapi.cn",
171		TrafficManagerDNSSuffix:      "trafficmanager.cn",
172		KeyVaultDNSSuffix:            "vault.azure.cn",
173		ServiceBusEndpointSuffix:     "servicebus.chinacloudapi.cn",
174		ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
175		ResourceManagerVMDNSSuffix:   "cloudapp.chinacloudapi.cn",
176		ContainerRegistryDNSSuffix:   "azurecr.cn",
177		CosmosDBDNSSuffix:            "documents.azure.cn",
178		TokenAudience:                "https://management.chinacloudapi.cn/",
179		APIManagementHostNameSuffix:  "azure-api.cn",
180		SynapseEndpointSuffix:        "dev.azuresynapse.azure.cn",
181		ResourceIdentifiers: ResourceIdentifier{
182			Graph:               "https://graph.chinacloudapi.cn/",
183			KeyVault:            "https://vault.azure.cn",
184			Datalake:            NotAvailable,
185			Batch:               "https://batch.chinacloudapi.cn/",
186			OperationalInsights: NotAvailable,
187			Storage:             "https://storage.azure.com/",
188			Synapse:             "https://dev.azuresynapse.net",
189			ServiceBus:          "https://servicebus.azure.net/",
190		},
191	}
192
193	// GermanCloud is the cloud environment operated in Germany
194	GermanCloud = Environment{
195		Name:                         "AzureGermanCloud",
196		ManagementPortalURL:          "http://portal.microsoftazure.de/",
197		PublishSettingsURL:           "https://manage.microsoftazure.de/publishsettings/index",
198		ServiceManagementEndpoint:    "https://management.core.cloudapi.de/",
199		ResourceManagerEndpoint:      "https://management.microsoftazure.de/",
200		ActiveDirectoryEndpoint:      "https://login.microsoftonline.de/",
201		GalleryEndpoint:              "https://gallery.cloudapi.de/",
202		KeyVaultEndpoint:             "https://vault.microsoftazure.de/",
203		GraphEndpoint:                "https://graph.cloudapi.de/",
204		ServiceBusEndpoint:           "https://servicebus.cloudapi.de/",
205		BatchManagementEndpoint:      "https://batch.cloudapi.de/",
206		StorageEndpointSuffix:        "core.cloudapi.de",
207		SQLDatabaseDNSSuffix:         "database.cloudapi.de",
208		TrafficManagerDNSSuffix:      "azuretrafficmanager.de",
209		KeyVaultDNSSuffix:            "vault.microsoftazure.de",
210		ServiceBusEndpointSuffix:     "servicebus.cloudapi.de",
211		ServiceManagementVMDNSSuffix: "azurecloudapp.de",
212		ResourceManagerVMDNSSuffix:   "cloudapp.microsoftazure.de",
213		ContainerRegistryDNSSuffix:   NotAvailable,
214		CosmosDBDNSSuffix:            "documents.microsoftazure.de",
215		TokenAudience:                "https://management.microsoftazure.de/",
216		APIManagementHostNameSuffix:  NotAvailable,
217		SynapseEndpointSuffix:        NotAvailable,
218		ResourceIdentifiers: ResourceIdentifier{
219			Graph:               "https://graph.cloudapi.de/",
220			KeyVault:            "https://vault.microsoftazure.de",
221			Datalake:            NotAvailable,
222			Batch:               "https://batch.cloudapi.de/",
223			OperationalInsights: NotAvailable,
224			Storage:             "https://storage.azure.com/",
225			Synapse:             NotAvailable,
226			ServiceBus:          "https://servicebus.azure.net/",
227		},
228	}
229)
230
231// EnvironmentFromName returns an Environment based on the common name specified.
232func EnvironmentFromName(name string) (Environment, error) {
233	// IMPORTANT
234	// As per @radhikagupta5:
235	// This is technical debt, fundamentally here because Kubernetes is not currently accepting
236	// contributions to the providers. Once that is an option, the provider should be updated to
237	// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
238	// from this method based on the name that is provided to us.
239	if strings.EqualFold(name, "AZURESTACKCLOUD") {
240		return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
241	}
242
243	name = strings.ToUpper(name)
244	env, ok := environments[name]
245	if !ok {
246		return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
247	}
248
249	return env, nil
250}
251
252// EnvironmentFromFile loads an Environment from a configuration file available on disk.
253// This function is particularly useful in the Hybrid Cloud model, where one must define their own
254// endpoints.
255func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
256	fileContents, err := ioutil.ReadFile(location)
257	if err != nil {
258		return
259	}
260
261	err = json.Unmarshal(fileContents, &unmarshaled)
262
263	return
264}
265
266// SetEnvironment updates the environment map with the specified values.
267func SetEnvironment(name string, env Environment) {
268	environments[strings.ToUpper(name)] = env
269}
270