metadata_environment.go raw

   1  package azure
   2  
   3  import (
   4  	"encoding/json"
   5  	"fmt"
   6  	"io"
   7  	"net/http"
   8  	"strings"
   9  
  10  	"github.com/Azure/go-autorest/autorest"
  11  )
  12  
  13  // Copyright 2017 Microsoft Corporation
  14  //
  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
  18  //
  19  //      http://www.apache.org/licenses/LICENSE-2.0
  20  //
  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.
  26  
  27  type audience []string
  28  
  29  type authentication struct {
  30  	LoginEndpoint string   `json:"loginEndpoint"`
  31  	Audiences     audience `json:"audiences"`
  32  }
  33  
  34  type environmentMetadataInfo struct {
  35  	GalleryEndpoint string         `json:"galleryEndpoint"`
  36  	GraphEndpoint   string         `json:"graphEndpoint"`
  37  	PortalEndpoint  string         `json:"portalEndpoint"`
  38  	Authentication  authentication `json:"authentication"`
  39  }
  40  
  41  // EnvironmentProperty represent property names that clients can override
  42  type EnvironmentProperty string
  43  
  44  const (
  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"
  85  )
  86  
  87  // OverrideProperty represents property name and value that clients can override
  88  type OverrideProperty struct {
  89  	Key   EnvironmentProperty
  90  	Value string
  91  }
  92  
  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
  95  // endpoints.
  96  func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) {
  97  	var metadataEnvProperties environmentMetadataInfo
  98  
  99  	if resourceManagerEndpoint == "" {
 100  		return environment, fmt.Errorf("Metadata resource manager endpoint is empty")
 101  	}
 102  
 103  	if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil {
 104  		return environment, err
 105  	}
 106  
 107  	// Give priority to user's override values
 108  	overrideProperties(&environment, properties)
 109  
 110  	if environment.Name == "" {
 111  		environment.Name = "HybridEnvironment"
 112  	}
 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
 117  	}
 118  	if environment.KeyVaultDNSSuffix == "" {
 119  		environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix)
 120  	}
 121  	if environment.KeyVaultEndpoint == "" {
 122  		environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix)
 123  	}
 124  	if environment.TokenAudience == "" {
 125  		environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0]
 126  	}
 127  	if environment.ActiveDirectoryEndpoint == "" {
 128  		environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint
 129  	}
 130  	if environment.ResourceManagerEndpoint == "" {
 131  		environment.ResourceManagerEndpoint = resourceManagerEndpoint
 132  	}
 133  	if environment.GalleryEndpoint == "" {
 134  		environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint
 135  	}
 136  	if environment.GraphEndpoint == "" {
 137  		environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint
 138  	}
 139  
 140  	return environment, nil
 141  }
 142  
 143  func overrideProperties(environment *Environment, properties []OverrideProperty) {
 144  	for _, property := range properties {
 145  		switch property.Key {
 146  		case EnvironmentName:
 147  			{
 148  				environment.Name = property.Value
 149  			}
 150  		case EnvironmentManagementPortalURL:
 151  			{
 152  				environment.ManagementPortalURL = property.Value
 153  			}
 154  		case EnvironmentPublishSettingsURL:
 155  			{
 156  				environment.PublishSettingsURL = property.Value
 157  			}
 158  		case EnvironmentServiceManagementEndpoint:
 159  			{
 160  				environment.ServiceManagementEndpoint = property.Value
 161  			}
 162  		case EnvironmentResourceManagerEndpoint:
 163  			{
 164  				environment.ResourceManagerEndpoint = property.Value
 165  			}
 166  		case EnvironmentActiveDirectoryEndpoint:
 167  			{
 168  				environment.ActiveDirectoryEndpoint = property.Value
 169  			}
 170  		case EnvironmentGalleryEndpoint:
 171  			{
 172  				environment.GalleryEndpoint = property.Value
 173  			}
 174  		case EnvironmentKeyVaultEndpoint:
 175  			{
 176  				environment.KeyVaultEndpoint = property.Value
 177  			}
 178  		case EnvironmentGraphEndpoint:
 179  			{
 180  				environment.GraphEndpoint = property.Value
 181  			}
 182  		case EnvironmentServiceBusEndpoint:
 183  			{
 184  				environment.ServiceBusEndpoint = property.Value
 185  			}
 186  		case EnvironmentBatchManagementEndpoint:
 187  			{
 188  				environment.BatchManagementEndpoint = property.Value
 189  			}
 190  		case EnvironmentStorageEndpointSuffix:
 191  			{
 192  				environment.StorageEndpointSuffix = property.Value
 193  			}
 194  		case EnvironmentSQLDatabaseDNSSuffix:
 195  			{
 196  				environment.SQLDatabaseDNSSuffix = property.Value
 197  			}
 198  		case EnvironmentTrafficManagerDNSSuffix:
 199  			{
 200  				environment.TrafficManagerDNSSuffix = property.Value
 201  			}
 202  		case EnvironmentKeyVaultDNSSuffix:
 203  			{
 204  				environment.KeyVaultDNSSuffix = property.Value
 205  			}
 206  		case EnvironmentServiceBusEndpointSuffix:
 207  			{
 208  				environment.ServiceBusEndpointSuffix = property.Value
 209  			}
 210  		case EnvironmentServiceManagementVMDNSSuffix:
 211  			{
 212  				environment.ServiceManagementVMDNSSuffix = property.Value
 213  			}
 214  		case EnvironmentResourceManagerVMDNSSuffix:
 215  			{
 216  				environment.ResourceManagerVMDNSSuffix = property.Value
 217  			}
 218  		case EnvironmentContainerRegistryDNSSuffix:
 219  			{
 220  				environment.ContainerRegistryDNSSuffix = property.Value
 221  			}
 222  		case EnvironmentTokenAudience:
 223  			{
 224  				environment.TokenAudience = property.Value
 225  			}
 226  		}
 227  	}
 228  }
 229  
 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)
 235  	if err != nil {
 236  		return environment, err
 237  	}
 238  	defer response.Body.Close()
 239  	jsonResponse, err := io.ReadAll(response.Body)
 240  	if err != nil {
 241  		return environment, err
 242  	}
 243  	err = json.Unmarshal(jsonResponse, &environment)
 244  	return environment, err
 245  }
 246