From 9e9a00bf4f9cfbd6f3a42664395106fa14d594b4 Mon Sep 17 00:00:00 2001 From: Mingliang Wang Date: Tue, 25 Aug 2020 17:24:37 +0800 Subject: [PATCH] [github #4555][devops #1761663] [Bug fixes] Azure CLI authentication does not show subscriptions for all tenants --- .../sdkmanage/AccessTokenAzureManager.java | 90 +------------------ .../sdkmanage/AzureCliAzureManager.java | 32 ++----- .../sdkmanage/AzureManagerBase.java | 71 +++++++++++++++ .../ServicePrincipalAzureManager.java | 27 +----- 4 files changed, 82 insertions(+), 138 deletions(-) diff --git a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AccessTokenAzureManager.java b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AccessTokenAzureManager.java index da90dd00631..410a95cf91b 100644 --- a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AccessTokenAzureManager.java +++ b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AccessTokenAzureManager.java @@ -27,8 +27,6 @@ import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.applicationinsights.v2015_05_01.implementation.InsightsManager; import com.microsoft.azure.management.appplatform.v2019_05_01_preview.implementation.AppPlatformManager; -import com.microsoft.azure.management.resources.Subscription; -import com.microsoft.azure.management.resources.Tenant; import com.microsoft.azuretools.adauth.PromptBehavior; import com.microsoft.azuretools.adauth.StringUtils; import com.microsoft.azuretools.authmanage.AdAuthManagerBuilder; @@ -36,21 +34,13 @@ import com.microsoft.azuretools.authmanage.BaseADAuthManager; import com.microsoft.azuretools.authmanage.CommonSettings; import com.microsoft.azuretools.authmanage.Environment; -import com.microsoft.azuretools.authmanage.RefreshableTokenCredentials; import com.microsoft.azuretools.authmanage.SubscriptionManager; import com.microsoft.azuretools.authmanage.SubscriptionManagerPersist; import com.microsoft.azuretools.authmanage.models.AuthMethodDetails; -import com.microsoft.azuretools.telemetry.TelemetryInterceptor; import com.microsoft.azuretools.utils.AzureRegisterProviderNamespaces; -import com.microsoft.azuretools.utils.Pair; import com.microsoft.rest.credentials.ServiceClientCredentials; -import rx.Observable; import java.io.IOException; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.logging.Logger; import static com.microsoft.azuretools.Constants.FILE_NAME_SUBSCRIPTIONS_DETAILS_AT; import static org.apache.commons.lang3.StringUtils.isBlank; @@ -90,7 +80,6 @@ public BaseADAuthManager getInstance() { } } - private static final Logger LOGGER = Logger.getLogger(AccessTokenAzureManager.class.getName()); private final SubscriptionManager subscriptionManager; private final BaseADAuthManager delegateADAuthManager; @@ -123,7 +112,7 @@ public Azure getAzure(String sid) throws IOException { return sidToAzureMap.get(sid); } String tid = subscriptionManager.getSubscriptionTenant(sid); - Azure azure = authTid(tid).withSubscription(sid); + Azure azure = authTenant(tid).withSubscription(sid); // TODO: remove this call after Azure SDK properly implements handling of unregistered provider namespaces AzureRegisterProviderNamespaces.registerAzureNamespaces(azure); sidToAzureMap.put(sid, azure); @@ -146,85 +135,14 @@ public InsightsManager getInsightsManager(String sid) { }); } - @Override - public List getSubscriptions() throws IOException { - List sl = new LinkedList(); - // could be multi tenant - return all subscriptions for the current account - List tl = getTenants(delegateADAuthManager.getCommonTenantId()); - for (Tenant t : tl) { - sl.addAll(getSubscriptions(t.tenantId())); - } - return sl; - } - - @Override - public List> getSubscriptionsWithTenant() throws IOException { - List> stl = new LinkedList<>(); - for (Tenant t : getTenants(delegateADAuthManager.getCommonTenantId())) { - String tid = t.tenantId(); - for (Subscription s : getSubscriptions(tid)) { - stl.add(new Pair(s, t)); - } - } - return stl; - } - @Override public Settings getSettings() { return settings; } - public List getSubscriptions(String tid) throws IOException { - List sl = authTid(tid).subscriptions().listAsync() - .onErrorResumeNext(err -> { - LOGGER.warning(err.getMessage()); - - return Observable.empty(); - }) - .toList() - .toBlocking() - .singleOrDefault(Collections.emptyList()); - - return sl; - } - - public List getTenants(String tid) throws IOException { - List tl = authTid(tid).tenants().listAsync() - .onErrorResumeNext(err -> { - LOGGER.warning(err.getMessage()); - - return Observable.empty(); - }) - .toList() - .toBlocking() - .singleOrDefault(Collections.emptyList()); - - return tl; - } - - // public static Azure.Authenticated auth(String accessToken) throws Exception { - // return Azure.configure().authenticate(getTokenCredentials(accessToken)); - // } - - // private static TokenCredentials getTokenCredentials(String token) throws Exception { - // return null; - // } - - private Azure.Authenticated authTid(String tid) throws IOException { - return Azure.configure() - .withInterceptor(new TelemetryInterceptor()) - .withUserAgent(CommonSettings.USER_AGENT) - .authenticate(new RefreshableTokenCredentials(this, tid)); - } - - private AppPlatformManager authSpringCloud(String sid, String tid) { - return buildAzureManager(AppPlatformManager.configure()) - .authenticate(new RefreshableTokenCredentials(this, tid), sid); - } - - private InsightsManager authApplicationInsights(String sid, String tid) { - return buildAzureManager(InsightsManager.configure()) - .authenticate(new RefreshableTokenCredentials(this, tid), sid); + @Override + protected String getTenantId() { + return delegateADAuthManager.getCommonTenantId(); } @Override diff --git a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java index d1a9e66ef29..d3d3768abb2 100644 --- a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java +++ b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureCliAzureManager.java @@ -31,8 +31,6 @@ import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.applicationinsights.v2015_05_01.implementation.InsightsManager; import com.microsoft.azure.management.appplatform.v2019_05_01_preview.implementation.AppPlatformManager; -import com.microsoft.azure.management.resources.Subscription; -import com.microsoft.azure.management.resources.Tenant; import com.microsoft.azuretools.adauth.PromptBehavior; import com.microsoft.azuretools.authmanage.AuthMethod; import com.microsoft.azuretools.authmanage.AzureManagerFactory; @@ -44,20 +42,18 @@ import com.microsoft.azuretools.azurecommons.helpers.Nullable; import com.microsoft.azuretools.telemetry.TelemetryInterceptor; import com.microsoft.azuretools.utils.AzureRegisterProviderNamespaces; -import com.microsoft.azuretools.utils.Pair; import com.microsoft.rest.credentials.ServiceClientCredentials; import org.apache.commons.lang.ObjectUtils; -import org.apache.commons.lang3.StringUtils; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.logging.Logger; import static com.microsoft.azuretools.Constants.FILE_NAME_SUBSCRIPTIONS_DETAILS_AZ; import static com.microsoft.azuretools.authmanage.Environment.ENVIRONMENT_LIST; public class AzureCliAzureManager extends AzureManagerBase { + private static final Logger LOGGER = Logger.getLogger(AzureCliAzureManager.class.getName()); + private static final String FAILED_TO_AUTH_WITH_AZURE_CLI = "Failed to auth with Azure CLI"; private static final String UNABLE_TO_GET_AZURE_CLI_CREDENTIALS = "Unable to get Azure CLI credentials, " + "please ensure you have installed Azure CLI and signed in."; @@ -124,26 +120,8 @@ public InsightsManager getInsightsManager(String sid) { } @Override - public List getSubscriptions() { - return isSignedIn() ? authenticated.subscriptions().list() : Collections.EMPTY_LIST; - } - - @Override - public List> getSubscriptionsWithTenant() { - if (!isSignedIn()) { - return Collections.EMPTY_LIST; - } - final Tenant subscriptionTenant = authenticated.tenants().list().stream() - .filter(tenant -> StringUtils.equals(tenant.tenantId(), authenticated.tenantId())) - .findFirst().orElse(null); - if (subscriptionTenant == null) { - return Collections.EMPTY_LIST; - } - final List> result = new ArrayList<>(); - for (Subscription subscription : getSubscriptions()) { - result.add(new Pair<>(subscription, subscriptionTenant)); - } - return result; + protected String getTenantId() { + return authenticated.tenantId(); } @Override diff --git a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureManagerBase.java b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureManagerBase.java index c4aa89330c4..cee7bd5b557 100644 --- a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureManagerBase.java +++ b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/AzureManagerBase.java @@ -31,13 +31,19 @@ import com.microsoft.azure.management.resources.Tenant; import com.microsoft.azuretools.authmanage.CommonSettings; import com.microsoft.azuretools.authmanage.Environment; +import com.microsoft.azuretools.authmanage.RefreshableTokenCredentials; import com.microsoft.azuretools.telemetry.TelemetryInterceptor; import com.microsoft.azuretools.utils.Pair; import org.apache.commons.lang3.StringUtils; +import rx.Observable; import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; +import java.util.logging.Logger; import static com.microsoft.azuretools.authmanage.Environment.*; @@ -54,6 +60,7 @@ public abstract class AzureManagerBase implements AzureManager { protected Map sidToAzureMap = new ConcurrentHashMap<>(); protected Map sidToAzureSpringCloudManagerMap = new ConcurrentHashMap<>(); protected Map sidToInsightsManagerMap = new ConcurrentHashMap<>(); + private static final Logger LOGGER = Logger.getLogger(AzureManagerBase.class.getName()); @Override public String getPortalUrl() { @@ -96,4 +103,68 @@ protected > T buildAzureManager(AzureConfigurable return configurable.withInterceptor(new TelemetryInterceptor()) .withUserAgent(CommonSettings.USER_AGENT); } + + protected abstract String getTenantId() throws IOException; + + @Override + public List getSubscriptions() throws IOException { + List sl = new LinkedList(); + // could be multi tenant - return all subscriptions for the current account + List tl = getTenants(getTenantId()); + for (Tenant t : tl) { + sl.addAll(getSubscriptions(t.tenantId())); + } + return sl; + } + + @Override + public List> getSubscriptionsWithTenant() throws IOException { + List> stl = new LinkedList<>(); + for (Tenant t : getTenants(getTenantId())) { + String tid = t.tenantId(); + for (Subscription s : getSubscriptions(tid)) { + stl.add(new Pair<>(s, t)); + } + } + return stl; + } + + private List getSubscriptions(String tid) { + return authTenant(tid).subscriptions().listAsync() + .onErrorResumeNext(err -> { + LOGGER.warning(err.getMessage()); + return Observable.empty(); + }) + .toList() + .toBlocking() + .singleOrDefault(Collections.emptyList()); + } + + private List getTenants(String tid) { + return authTenant(tid).tenants().listAsync() + .onErrorResumeNext(err -> { + LOGGER.warning(err.getMessage()); + return Observable.empty(); + }) + .toList() + .toBlocking() + .singleOrDefault(Collections.emptyList()); + } + + protected Azure.Authenticated authTenant(String tenantId) { + return Azure.configure() + .withInterceptor(new TelemetryInterceptor()) + .withUserAgent(CommonSettings.USER_AGENT) + .authenticate(new RefreshableTokenCredentials(this, tenantId)); + } + + protected AppPlatformManager authSpringCloud(String subscriptionId, String tenantId) { + return buildAzureManager(AppPlatformManager.configure()) + .authenticate(new RefreshableTokenCredentials(this, tenantId), subscriptionId); + } + + protected InsightsManager authApplicationInsights(String subscriptionId, String tenantId) { + return buildAzureManager(InsightsManager.configure()) + .authenticate(new RefreshableTokenCredentials(this, tenantId), subscriptionId); + } } diff --git a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/ServicePrincipalAzureManager.java b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/ServicePrincipalAzureManager.java index 6e5ae546333..441ca0f2749 100644 --- a/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/ServicePrincipalAzureManager.java +++ b/Utils/azuretools-core/src/com/microsoft/azuretools/sdkmanage/ServicePrincipalAzureManager.java @@ -32,8 +32,6 @@ import com.microsoft.azure.keyvault.KeyVaultClient; import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials; import com.microsoft.azure.management.Azure; -import com.microsoft.azure.management.resources.Subscription; -import com.microsoft.azure.management.resources.Tenant; import com.microsoft.azuretools.adauth.PromptBehavior; import com.microsoft.azuretools.authmanage.AzureManagerFactory; import com.microsoft.azuretools.authmanage.CommonSettings; @@ -44,7 +42,6 @@ import com.microsoft.azuretools.authmanage.models.AuthMethodDetails; import com.microsoft.azuretools.telemetry.TelemetryInterceptor; import com.microsoft.azuretools.utils.AzureRegisterProviderNamespaces; -import com.microsoft.azuretools.utils.Pair; import com.microsoft.rest.credentials.ServiceClientCredentials; import java.io.File; @@ -52,8 +49,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.LinkedList; -import java.util.List; import java.util.logging.Logger; import static com.microsoft.azuretools.Constants.FILE_NAME_SUBSCRIPTIONS_DETAILS_SP; @@ -154,21 +149,8 @@ public InsightsManager getInsightsManager(String sid) throws IOException { } @Override - public List getSubscriptions() throws IOException { - List sl = auth().subscriptions().list(); - return sl; - } - - @Override - public List> getSubscriptionsWithTenant() throws IOException { - List> stl = new LinkedList<>(); - for (Tenant t : getTenants()) { - //String tid = t.tenantId(); - for (Subscription s : getSubscriptions()) { - stl.add(new Pair<>(s, t)); - } - } - return stl; + protected String getTenantId() throws IOException { + return auth().tenantId(); } @Override @@ -187,11 +169,6 @@ public void drop() throws IOException { subscriptionManager.cleanSubscriptions(); } - public List getTenants() throws IOException { - List tl = auth().tenants().list(); - return tl; - } - @Override public KeyVaultClient getKeyVaultClient(String tid) { ServiceClientCredentials creds = new KeyVaultCredentials() {