github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/provider/azure/internal/azurecli/az_test.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package azurecli_test 5 6 import ( 7 "os/exec" 8 "strings" 9 10 "github.com/Azure/go-autorest/autorest/adal" 11 "github.com/juju/errors" 12 "github.com/juju/juju/provider/azure/internal/azurecli" 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 ) 16 17 type azSuite struct{} 18 19 var _ = gc.Suite(&azSuite{}) 20 21 func (s *azSuite) TestGetAccessToken(c *gc.C) { 22 azcli := azurecli.AzureCLI{ 23 Exec: testExecutor{ 24 commands: map[string]result{ 25 "az account get-access-token -o json": { 26 stdout: []byte(` 27 { 28 "accessToken": "ACCESSTOKEN", 29 "expiresOn": "2017-06-07 09:27:58.063743", 30 "subscription": "5544b9a5-0000-0000-0000-fedceb5d3696", 31 "tenant": "a52afd7f-0000-0000-0000-e47a54b982da", 32 "tokenType": "Bearer" 33 } 34 `[1:]), 35 }, 36 }, 37 }.Exec, 38 } 39 tok, err := azcli.GetAccessToken("", "") 40 c.Assert(err, jc.ErrorIsNil) 41 c.Assert(tok, jc.DeepEquals, &azurecli.AccessToken{ 42 AccessToken: "ACCESSTOKEN", 43 ExpiresOn: "2017-06-07 09:27:58.063743", 44 Subscription: "5544b9a5-0000-0000-0000-fedceb5d3696", 45 Tenant: "a52afd7f-0000-0000-0000-e47a54b982da", 46 TokenType: "Bearer", 47 }) 48 } 49 50 func (s *azSuite) TestGetAccessTokenWithSubscriptionAndResource(c *gc.C) { 51 azcli := azurecli.AzureCLI{ 52 Exec: testExecutor{ 53 commands: map[string]result{ 54 "az account get-access-token --subscription 5544b9a5-0000-0000-0000-fedceb5d3696 --resource resid -o json": { 55 stdout: []byte(` 56 { 57 "accessToken": "ACCESSTOKEN", 58 "expiresOn": "2017-06-07 09:27:58.063743", 59 "subscription": "5544b9a5-0000-0000-0000-fedceb5d3696", 60 "tenant": "a52afd7f-0000-0000-0000-e47a54b982da", 61 "tokenType": "Bearer" 62 } 63 `[1:]), 64 }, 65 }, 66 }.Exec, 67 } 68 tok, err := azcli.GetAccessToken("5544b9a5-0000-0000-0000-fedceb5d3696", "resid") 69 c.Assert(err, jc.ErrorIsNil) 70 c.Assert(tok, jc.DeepEquals, &azurecli.AccessToken{ 71 AccessToken: "ACCESSTOKEN", 72 ExpiresOn: "2017-06-07 09:27:58.063743", 73 Subscription: "5544b9a5-0000-0000-0000-fedceb5d3696", 74 Tenant: "a52afd7f-0000-0000-0000-e47a54b982da", 75 TokenType: "Bearer", 76 }) 77 } 78 79 func (s *azSuite) TestGetAccessTokenError(c *gc.C) { 80 azcli := azurecli.AzureCLI{ 81 Exec: testExecutor{ 82 commands: map[string]result{ 83 "az account get-access-token -o json": { 84 error: &exec.ExitError{Stderr: []byte("test error")}, 85 }, 86 }, 87 }.Exec, 88 } 89 tok, err := azcli.GetAccessToken("", "") 90 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 91 c.Assert(tok, gc.IsNil) 92 } 93 94 func (s *azSuite) TestGetAccessTokenJSONError(c *gc.C) { 95 azcli := azurecli.AzureCLI{ 96 Exec: testExecutor{ 97 commands: map[string]result{ 98 "az account get-access-token -o json": { 99 stdout: []byte(`}`), 100 }, 101 }, 102 }.Exec, 103 } 104 tok, err := azcli.GetAccessToken("", "") 105 c.Assert(err, gc.ErrorMatches, `cannot unmarshal output: invalid character '}' looking for beginning of value`) 106 c.Assert(tok, gc.IsNil) 107 } 108 109 func (s *azSuite) TestAzureTokenFromAccessToken(c *gc.C) { 110 tok := azurecli.AccessToken{ 111 AccessToken: "0123456789", 112 ExpiresOn: "2017-06-05 10:20:43.752534", 113 Subscription: "00000000-0000-0000-0000-00000001", 114 Tenant: "00000000-0000-0000-0000-00000002", 115 TokenType: "Bearer", 116 } 117 tok1 := tok.Token() 118 c.Assert(tok1, jc.DeepEquals, &adal.Token{ 119 AccessToken: "0123456789", 120 Type: "Bearer", 121 }) 122 } 123 124 func (s *azSuite) TestShowAccount(c *gc.C) { 125 azcli := azurecli.AzureCLI{ 126 Exec: testExecutor{ 127 commands: map[string]result{ 128 "az account show -o json": { 129 stdout: []byte(` 130 { 131 "environmentName": "AzureCloud", 132 "id": "5544b9a5-0000-0000-0000-fedceb5d3696", 133 "isDefault": true, 134 "name": "AccountName", 135 "state": "Enabled", 136 "tenantId": "a52afd7f-0000-0000-0000-e47a54b982da", 137 "user": { 138 "name": "user@example.com", 139 "type": "user" 140 } 141 } 142 143 `[1:]), 144 }, 145 }, 146 }.Exec, 147 } 148 acc, err := azcli.ShowAccount("") 149 c.Assert(err, jc.ErrorIsNil) 150 c.Assert(acc, jc.DeepEquals, &azurecli.Account{ 151 CloudName: "AzureCloud", 152 ID: "5544b9a5-0000-0000-0000-fedceb5d3696", 153 IsDefault: true, 154 Name: "AccountName", 155 State: "Enabled", 156 TenantId: "a52afd7f-0000-0000-0000-e47a54b982da", 157 }) 158 } 159 160 func (s *azSuite) TestShowAccountWithSubscription(c *gc.C) { 161 azcli := azurecli.AzureCLI{ 162 Exec: testExecutor{ 163 commands: map[string]result{ 164 "az account show --subscription 5544b9a5-0000-0000-0000-fedceb5d3696 -o json": { 165 stdout: []byte(` 166 { 167 "environmentName": "AzureCloud", 168 "id": "5544b9a5-0000-0000-0000-fedceb5d3696", 169 "isDefault": true, 170 "name": "AccountName", 171 "state": "Enabled", 172 "tenantId": "a52afd7f-0000-0000-0000-e47a54b982da", 173 "user": { 174 "name": "user@example.com", 175 "type": "user" 176 } 177 } 178 179 `[1:]), 180 }, 181 }, 182 }.Exec, 183 } 184 acc, err := azcli.ShowAccount("5544b9a5-0000-0000-0000-fedceb5d3696") 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(acc, jc.DeepEquals, &azurecli.Account{ 187 CloudName: "AzureCloud", 188 ID: "5544b9a5-0000-0000-0000-fedceb5d3696", 189 IsDefault: true, 190 Name: "AccountName", 191 State: "Enabled", 192 TenantId: "a52afd7f-0000-0000-0000-e47a54b982da", 193 }) 194 } 195 196 func (s *azSuite) TestShowAccountError(c *gc.C) { 197 azcli := azurecli.AzureCLI{ 198 Exec: testExecutor{ 199 commands: map[string]result{ 200 "az account show -o json": { 201 error: &exec.ExitError{Stderr: []byte("test error\nusage ...")}, 202 }, 203 }, 204 }.Exec, 205 } 206 acc, err := azcli.ShowAccount("") 207 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 208 c.Assert(acc, gc.IsNil) 209 } 210 211 func (s *azSuite) TestListAccounts(c *gc.C) { 212 azcli := azurecli.AzureCLI{ 213 Exec: testExecutor{ 214 commands: map[string]result{ 215 "az account list -o json": { 216 stdout: []byte(` 217 [ 218 { 219 "cloudName": "AzureCloud", 220 "id": "d7ad3057-0000-0000-0000-513d7136eec5", 221 "isDefault": false, 222 "name": "Free Trial", 223 "state": "Enabled", 224 "tenantId": "b7bb0664-0000-0000-0000-4d5f1481ef22", 225 "user": { 226 "name": "user@example.com", 227 "type": "user" 228 } 229 }, 230 { 231 "cloudName": "AzureCloud", 232 "id": "5af17b7d-0000-0000-0000-5cd99887fdf7", 233 "isDefault": true, 234 "name": "Pay-As-You-Go", 235 "state": "Enabled", 236 "tenantId": "2da419a9-0000-0000-0000-ac7c24bbe2e7", 237 "user": { 238 "name": "user@example.com", 239 "type": "user" 240 } 241 } 242 ] 243 `[1:]), 244 }, 245 }, 246 }.Exec, 247 } 248 accs, err := azcli.ListAccounts() 249 c.Assert(err, jc.ErrorIsNil) 250 c.Assert(accs, jc.DeepEquals, []azurecli.Account{{ 251 CloudName: "AzureCloud", 252 ID: "d7ad3057-0000-0000-0000-513d7136eec5", 253 IsDefault: false, 254 Name: "Free Trial", 255 State: "Enabled", 256 TenantId: "b7bb0664-0000-0000-0000-4d5f1481ef22", 257 }, { 258 CloudName: "AzureCloud", 259 ID: "5af17b7d-0000-0000-0000-5cd99887fdf7", 260 IsDefault: true, 261 Name: "Pay-As-You-Go", 262 State: "Enabled", 263 TenantId: "2da419a9-0000-0000-0000-ac7c24bbe2e7", 264 }}) 265 } 266 267 func (s *azSuite) TestListAccountsError(c *gc.C) { 268 azcli := azurecli.AzureCLI{ 269 Exec: testExecutor{ 270 commands: map[string]result{ 271 "az account list -o json": { 272 error: errors.New("test error"), 273 }, 274 }, 275 }.Exec, 276 } 277 accs, err := azcli.ListAccounts() 278 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 279 c.Assert(accs, gc.IsNil) 280 } 281 282 func (s *azSuite) TestFindAccountsWithCloudName(c *gc.C) { 283 azcli := azurecli.AzureCLI{ 284 Exec: testExecutor{ 285 commands: map[string]result{ 286 "az account list --query [?cloudName=='AzureCloud'] -o json": { 287 stdout: []byte(` 288 [ 289 { 290 "cloudName": "AzureCloud", 291 "id": "d7ad3057-0000-0000-0000-513d7136eec5", 292 "isDefault": false, 293 "name": "Free Trial", 294 "state": "Enabled", 295 "tenantId": "b7bb0664-0000-0000-0000-4d5f1481ef22", 296 "user": { 297 "name": "user@example.com", 298 "type": "user" 299 } 300 }, 301 { 302 "cloudName": "AzureCloud", 303 "id": "5af17b7d-0000-0000-0000-5cd99887fdf7", 304 "isDefault": true, 305 "name": "Pay-As-You-Go", 306 "state": "Enabled", 307 "tenantId": "2da419a9-0000-0000-0000-ac7c24bbe2e7", 308 "user": { 309 "name": "user@example.com", 310 "type": "user" 311 } 312 } 313 ] 314 `[1:]), 315 }, 316 }, 317 }.Exec, 318 } 319 accs, err := azcli.FindAccountsWithCloudName("AzureCloud") 320 c.Assert(err, jc.ErrorIsNil) 321 c.Assert(accs, jc.DeepEquals, []azurecli.Account{{ 322 CloudName: "AzureCloud", 323 ID: "d7ad3057-0000-0000-0000-513d7136eec5", 324 IsDefault: false, 325 Name: "Free Trial", 326 State: "Enabled", 327 TenantId: "b7bb0664-0000-0000-0000-4d5f1481ef22", 328 }, { 329 CloudName: "AzureCloud", 330 ID: "5af17b7d-0000-0000-0000-5cd99887fdf7", 331 IsDefault: true, 332 Name: "Pay-As-You-Go", 333 State: "Enabled", 334 TenantId: "2da419a9-0000-0000-0000-ac7c24bbe2e7", 335 }}) 336 } 337 338 func (s *azSuite) TestFindAccountsWithCloudNameError(c *gc.C) { 339 azcli := azurecli.AzureCLI{ 340 Exec: testExecutor{ 341 commands: map[string]result{ 342 "az account list --query [?cloudName=='AzureCloud'] -o json": { 343 error: errors.New("test error"), 344 }, 345 }, 346 }.Exec, 347 } 348 accs, err := azcli.FindAccountsWithCloudName("AzureCloud") 349 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 350 c.Assert(accs, gc.IsNil) 351 } 352 353 func (s *azSuite) TestShowCloud(c *gc.C) { 354 azcli := azurecli.AzureCLI{ 355 Exec: testExecutor{ 356 commands: map[string]result{ 357 "az cloud show -o json": { 358 stdout: []byte(` 359 { 360 "endpoints": { 361 "activeDirectory": "https://login.microsoftonline.com", 362 "activeDirectoryGraphResourceId": "https://graph.windows.net/", 363 "activeDirectoryResourceId": "https://management.core.windows.net/", 364 "batchResourceId": "https://batch.core.windows.net/", 365 "gallery": "https://gallery.azure.com/", 366 "management": "https://management.core.windows.net/", 367 "resourceManager": "https://management.azure.com/", 368 "sqlManagement": "https://management.core.windows.net:8443/" 369 }, 370 "isActive": true, 371 "name": "AzureCloud", 372 "profile": "latest", 373 "suffixes": { 374 "azureDatalakeAnalyticsCatalogAndJobEndpoint": "azuredatalakeanalytics.net", 375 "azureDatalakeStoreFileSystemEndpoint": "azuredatalakestore.net", 376 "keyvaultDns": ".vault.azure.net", 377 "sqlServerHostname": ".database.windows.net", 378 "storageEndpoint": "core.windows.net" 379 } 380 } 381 `[1:]), 382 }, 383 }, 384 }.Exec, 385 } 386 cloud, err := azcli.ShowCloud("") 387 c.Assert(err, jc.ErrorIsNil) 388 c.Assert(cloud, jc.DeepEquals, &azurecli.Cloud{ 389 Endpoints: azurecli.CloudEndpoints{ 390 ActiveDirectory: "https://login.microsoftonline.com", 391 ActiveDirectoryGraphResourceID: "https://graph.windows.net/", 392 ActiveDirectoryResourceID: "https://management.core.windows.net/", 393 BatchResourceID: "https://batch.core.windows.net/", 394 Management: "https://management.core.windows.net/", 395 ResourceManager: "https://management.azure.com/", 396 SQLManagement: "https://management.core.windows.net:8443/", 397 }, 398 IsActive: true, 399 Name: "AzureCloud", 400 Profile: "latest", 401 Suffixes: azurecli.CloudSuffixes{ 402 AzureDatalakeAnalyticsCatalogAndJobEndpoint: "azuredatalakeanalytics.net", 403 AzureDatalakeStoreFileSystemEndpoint: "azuredatalakestore.net", 404 KeyvaultDNS: ".vault.azure.net", 405 SQLServerHostname: ".database.windows.net", 406 StorageEndpoint: "core.windows.net", 407 }, 408 }) 409 } 410 411 func (s *azSuite) TestShowCloudWithName(c *gc.C) { 412 azcli := azurecli.AzureCLI{ 413 Exec: testExecutor{ 414 commands: map[string]result{ 415 "az cloud show --name AzureUSGovernment -o json": { 416 stdout: []byte(` 417 { 418 "endpoints": { 419 "activeDirectory": "https://login.microsoftonline.com", 420 "activeDirectoryGraphResourceId": "https://graph.windows.net/", 421 "activeDirectoryResourceId": "https://management.core.usgovcloudapi.net/", 422 "batchResourceId": "https://batch.core.usgovcloudapi.net/", 423 "gallery": "https://gallery.usgovcloudapi.net/", 424 "management": "https://management.core.usgovcloudapi.net/", 425 "resourceManager": "https://management.usgovcloudapi.net/", 426 "sqlManagement": "https://management.core.usgovcloudapi.net:8443/" 427 }, 428 "isActive": false, 429 "name": "AzureUSGovernment", 430 "profile": "latest", 431 "suffixes": { 432 "azureDatalakeAnalyticsCatalogAndJobEndpoint": null, 433 "azureDatalakeStoreFileSystemEndpoint": null, 434 "keyvaultDns": ".vault.usgovcloudapi.net", 435 "sqlServerHostname": ".database.usgovcloudapi.net", 436 "storageEndpoint": "core.usgovcloudapi.net" 437 } 438 } 439 `[1:]), 440 }, 441 }, 442 }.Exec, 443 } 444 cloud, err := azcli.ShowCloud("AzureUSGovernment") 445 c.Assert(err, jc.ErrorIsNil) 446 c.Assert(cloud, jc.DeepEquals, &azurecli.Cloud{ 447 Endpoints: azurecli.CloudEndpoints{ 448 ActiveDirectory: "https://login.microsoftonline.com", 449 ActiveDirectoryGraphResourceID: "https://graph.windows.net/", 450 ActiveDirectoryResourceID: "https://management.core.usgovcloudapi.net/", 451 BatchResourceID: "https://batch.core.usgovcloudapi.net/", 452 Management: "https://management.core.usgovcloudapi.net/", 453 ResourceManager: "https://management.usgovcloudapi.net/", 454 SQLManagement: "https://management.core.usgovcloudapi.net:8443/", 455 }, 456 IsActive: false, 457 Name: "AzureUSGovernment", 458 Profile: "latest", 459 Suffixes: azurecli.CloudSuffixes{ 460 KeyvaultDNS: ".vault.usgovcloudapi.net", 461 SQLServerHostname: ".database.usgovcloudapi.net", 462 StorageEndpoint: "core.usgovcloudapi.net", 463 }, 464 }) 465 } 466 467 func (s *azSuite) TestShowCloudError(c *gc.C) { 468 azcli := azurecli.AzureCLI{ 469 Exec: testExecutor{ 470 commands: map[string]result{ 471 "az cloud show -o json": { 472 error: errors.New("test error"), 473 }, 474 }, 475 }.Exec, 476 } 477 cloud, err := azcli.ShowCloud("") 478 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 479 c.Assert(cloud, gc.IsNil) 480 } 481 482 func (s *azSuite) TestFindCloudsWithResourceManagerEndpoint(c *gc.C) { 483 azcli := azurecli.AzureCLI{ 484 Exec: testExecutor{ 485 commands: map[string]result{ 486 "az cloud list --query [?endpoints.resourceManager=='https://management.azure.com/'] -o json": { 487 stdout: []byte(` 488 [ 489 { 490 "endpoints": { 491 "activeDirectory": "https://login.microsoftonline.com", 492 "activeDirectoryGraphResourceId": "https://graph.windows.net/", 493 "activeDirectoryResourceId": "https://management.core.windows.net/", 494 "batchResourceId": "https://batch.core.windows.net/", 495 "gallery": "https://gallery.azure.com/", 496 "management": "https://management.core.windows.net/", 497 "resourceManager": "https://management.azure.com/", 498 "sqlManagement": "https://management.core.windows.net:8443/" 499 }, 500 "isActive": true, 501 "name": "AzureCloud", 502 "profile": "latest", 503 "suffixes": { 504 "azureDatalakeAnalyticsCatalogAndJobEndpoint": "azuredatalakeanalytics.net", 505 "azureDatalakeStoreFileSystemEndpoint": "azuredatalakestore.net", 506 "keyvaultDns": ".vault.azure.net", 507 "sqlServerHostname": ".database.windows.net", 508 "storageEndpoint": "core.windows.net" 509 } 510 } 511 ] 512 `[1:]), 513 }, 514 }, 515 }.Exec, 516 } 517 cloud, err := azcli.FindCloudsWithResourceManagerEndpoint("https://management.azure.com/") 518 c.Assert(err, jc.ErrorIsNil) 519 c.Assert(cloud, jc.DeepEquals, []azurecli.Cloud{{ 520 Endpoints: azurecli.CloudEndpoints{ 521 ActiveDirectory: "https://login.microsoftonline.com", 522 ActiveDirectoryGraphResourceID: "https://graph.windows.net/", 523 ActiveDirectoryResourceID: "https://management.core.windows.net/", 524 BatchResourceID: "https://batch.core.windows.net/", 525 Management: "https://management.core.windows.net/", 526 ResourceManager: "https://management.azure.com/", 527 SQLManagement: "https://management.core.windows.net:8443/", 528 }, 529 IsActive: true, 530 Name: "AzureCloud", 531 Profile: "latest", 532 Suffixes: azurecli.CloudSuffixes{ 533 AzureDatalakeAnalyticsCatalogAndJobEndpoint: "azuredatalakeanalytics.net", 534 AzureDatalakeStoreFileSystemEndpoint: "azuredatalakestore.net", 535 KeyvaultDNS: ".vault.azure.net", 536 SQLServerHostname: ".database.windows.net", 537 StorageEndpoint: "core.windows.net", 538 }, 539 }}) 540 } 541 542 func (s *azSuite) TestFindCloudsWithResourceManagerEndpointError(c *gc.C) { 543 azcli := azurecli.AzureCLI{ 544 Exec: testExecutor{ 545 commands: map[string]result{ 546 "az cloud list --query [?endpoints.resourceManager=='https://management.azure.com/'] -o json": { 547 error: errors.New("test error"), 548 }, 549 }, 550 }.Exec, 551 } 552 cloud, err := azcli.FindCloudsWithResourceManagerEndpoint("https://management.azure.com/") 553 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 554 c.Assert(cloud, gc.IsNil) 555 } 556 557 func (s *azSuite) TestListClouds(c *gc.C) { 558 azcli := azurecli.AzureCLI{ 559 Exec: testExecutor{ 560 commands: map[string]result{ 561 "az cloud list -o json": { 562 stdout: []byte(` 563 [ 564 { 565 "endpoints": { 566 "activeDirectory": "https://login.microsoftonline.com", 567 "activeDirectoryGraphResourceId": "https://graph.windows.net/", 568 "activeDirectoryResourceId": "https://management.core.windows.net/", 569 "batchResourceId": "https://batch.core.windows.net/", 570 "gallery": "https://gallery.azure.com/", 571 "management": "https://management.core.windows.net/", 572 "resourceManager": "https://management.azure.com/", 573 "sqlManagement": "https://management.core.windows.net:8443/" 574 }, 575 "isActive": true, 576 "name": "AzureCloud", 577 "profile": "latest", 578 "suffixes": { 579 "azureDatalakeAnalyticsCatalogAndJobEndpoint": "azuredatalakeanalytics.net", 580 "azureDatalakeStoreFileSystemEndpoint": "azuredatalakestore.net", 581 "keyvaultDns": ".vault.azure.net", 582 "sqlServerHostname": ".database.windows.net", 583 "storageEndpoint": "core.windows.net" 584 } 585 }, 586 { 587 "endpoints": { 588 "activeDirectory": "https://login.chinacloudapi.cn", 589 "activeDirectoryGraphResourceId": "https://graph.chinacloudapi.cn/", 590 "activeDirectoryResourceId": "https://management.core.chinacloudapi.cn/", 591 "batchResourceId": "https://batch.chinacloudapi.cn/", 592 "gallery": "https://gallery.chinacloudapi.cn/", 593 "management": "https://management.core.chinacloudapi.cn/", 594 "resourceManager": "https://management.chinacloudapi.cn", 595 "sqlManagement": "https://management.core.chinacloudapi.cn:8443/" 596 }, 597 "isActive": false, 598 "name": "AzureChinaCloud", 599 "profile": "latest", 600 "suffixes": { 601 "azureDatalakeAnalyticsCatalogAndJobEndpoint": null, 602 "azureDatalakeStoreFileSystemEndpoint": null, 603 "keyvaultDns": ".vault.azure.cn", 604 "sqlServerHostname": ".database.chinacloudapi.cn", 605 "storageEndpoint": "core.chinacloudapi.cn" 606 } 607 }, 608 { 609 "endpoints": { 610 "activeDirectory": "https://login.microsoftonline.com", 611 "activeDirectoryGraphResourceId": "https://graph.windows.net/", 612 "activeDirectoryResourceId": "https://management.core.usgovcloudapi.net/", 613 "batchResourceId": "https://batch.core.usgovcloudapi.net/", 614 "gallery": "https://gallery.usgovcloudapi.net/", 615 "management": "https://management.core.usgovcloudapi.net/", 616 "resourceManager": "https://management.usgovcloudapi.net/", 617 "sqlManagement": "https://management.core.usgovcloudapi.net:8443/" 618 }, 619 "isActive": false, 620 "name": "AzureUSGovernment", 621 "profile": "latest", 622 "suffixes": { 623 "azureDatalakeAnalyticsCatalogAndJobEndpoint": null, 624 "azureDatalakeStoreFileSystemEndpoint": null, 625 "keyvaultDns": ".vault.usgovcloudapi.net", 626 "sqlServerHostname": ".database.usgovcloudapi.net", 627 "storageEndpoint": "core.usgovcloudapi.net" 628 } 629 }, 630 { 631 "endpoints": { 632 "activeDirectory": "https://login.microsoftonline.de", 633 "activeDirectoryGraphResourceId": "https://graph.cloudapi.de/", 634 "activeDirectoryResourceId": "https://management.core.cloudapi.de/", 635 "batchResourceId": "https://batch.cloudapi.de/", 636 "gallery": "https://gallery.cloudapi.de/", 637 "management": "https://management.core.cloudapi.de/", 638 "resourceManager": "https://management.microsoftazure.de", 639 "sqlManagement": "https://management.core.cloudapi.de:8443/" 640 }, 641 "isActive": false, 642 "name": "AzureGermanCloud", 643 "profile": "latest", 644 "suffixes": { 645 "azureDatalakeAnalyticsCatalogAndJobEndpoint": null, 646 "azureDatalakeStoreFileSystemEndpoint": null, 647 "keyvaultDns": ".vault.microsoftazure.de", 648 "sqlServerHostname": ".database.cloudapi.de", 649 "storageEndpoint": "core.cloudapi.de" 650 } 651 } 652 ] 653 654 `[1:]), 655 }, 656 }, 657 }.Exec, 658 } 659 clouds, err := azcli.ListClouds() 660 c.Assert(err, jc.ErrorIsNil) 661 c.Assert(clouds, jc.DeepEquals, []azurecli.Cloud{{ 662 Endpoints: azurecli.CloudEndpoints{ 663 ActiveDirectory: "https://login.microsoftonline.com", 664 ActiveDirectoryGraphResourceID: "https://graph.windows.net/", 665 ActiveDirectoryResourceID: "https://management.core.windows.net/", 666 BatchResourceID: "https://batch.core.windows.net/", 667 Management: "https://management.core.windows.net/", 668 ResourceManager: "https://management.azure.com/", 669 SQLManagement: "https://management.core.windows.net:8443/", 670 }, 671 IsActive: true, 672 Name: "AzureCloud", 673 Profile: "latest", 674 Suffixes: azurecli.CloudSuffixes{ 675 AzureDatalakeAnalyticsCatalogAndJobEndpoint: "azuredatalakeanalytics.net", 676 AzureDatalakeStoreFileSystemEndpoint: "azuredatalakestore.net", 677 KeyvaultDNS: ".vault.azure.net", 678 SQLServerHostname: ".database.windows.net", 679 StorageEndpoint: "core.windows.net", 680 }, 681 }, { 682 Endpoints: azurecli.CloudEndpoints{ 683 ActiveDirectory: "https://login.chinacloudapi.cn", 684 ActiveDirectoryGraphResourceID: "https://graph.chinacloudapi.cn/", 685 ActiveDirectoryResourceID: "https://management.core.chinacloudapi.cn/", 686 BatchResourceID: "https://batch.chinacloudapi.cn/", 687 Management: "https://management.core.chinacloudapi.cn/", 688 ResourceManager: "https://management.chinacloudapi.cn", 689 SQLManagement: "https://management.core.chinacloudapi.cn:8443/", 690 }, 691 IsActive: false, 692 Name: "AzureChinaCloud", 693 Profile: "latest", 694 Suffixes: azurecli.CloudSuffixes{ 695 KeyvaultDNS: ".vault.azure.cn", 696 SQLServerHostname: ".database.chinacloudapi.cn", 697 StorageEndpoint: "core.chinacloudapi.cn", 698 }, 699 }, { 700 Endpoints: azurecli.CloudEndpoints{ 701 ActiveDirectory: "https://login.microsoftonline.com", 702 ActiveDirectoryGraphResourceID: "https://graph.windows.net/", 703 ActiveDirectoryResourceID: "https://management.core.usgovcloudapi.net/", 704 BatchResourceID: "https://batch.core.usgovcloudapi.net/", 705 Management: "https://management.core.usgovcloudapi.net/", 706 ResourceManager: "https://management.usgovcloudapi.net/", 707 SQLManagement: "https://management.core.usgovcloudapi.net:8443/", 708 }, 709 IsActive: false, 710 Name: "AzureUSGovernment", 711 Profile: "latest", 712 Suffixes: azurecli.CloudSuffixes{ 713 KeyvaultDNS: ".vault.usgovcloudapi.net", 714 SQLServerHostname: ".database.usgovcloudapi.net", 715 StorageEndpoint: "core.usgovcloudapi.net", 716 }, 717 }, { 718 Endpoints: azurecli.CloudEndpoints{ 719 ActiveDirectory: "https://login.microsoftonline.de", 720 ActiveDirectoryGraphResourceID: "https://graph.cloudapi.de/", 721 ActiveDirectoryResourceID: "https://management.core.cloudapi.de/", 722 BatchResourceID: "https://batch.cloudapi.de/", 723 Management: "https://management.core.cloudapi.de/", 724 ResourceManager: "https://management.microsoftazure.de", 725 SQLManagement: "https://management.core.cloudapi.de:8443/", 726 }, 727 IsActive: false, 728 Name: "AzureGermanCloud", 729 Profile: "latest", 730 Suffixes: azurecli.CloudSuffixes{ 731 KeyvaultDNS: ".vault.microsoftazure.de", 732 SQLServerHostname: ".database.cloudapi.de", 733 StorageEndpoint: "core.cloudapi.de", 734 }, 735 }}) 736 } 737 738 func (s *azSuite) TestListCloudsError(c *gc.C) { 739 azcli := azurecli.AzureCLI{ 740 Exec: testExecutor{ 741 commands: map[string]result{ 742 "az cloud list -o json": { 743 error: errors.New("test error"), 744 }, 745 }, 746 }.Exec, 747 } 748 cloud, err := azcli.ListClouds() 749 c.Assert(err, gc.ErrorMatches, `execution failure: test error`) 750 c.Assert(cloud, gc.IsNil) 751 } 752 753 type result struct { 754 stdout []byte 755 error error 756 } 757 758 type testExecutor struct { 759 commands map[string]result 760 } 761 762 func (e testExecutor) Exec(cmd string, args []string) ([]byte, error) { 763 c := strings.Join(append([]string{cmd}, args...), " ") 764 r, ok := e.commands[c] 765 if !ok { 766 return nil, errors.Errorf("unexpected command '%s'", c) 767 } 768 return r.stdout, r.error 769 }