cli: Add "Demo Mode" which hides subscription IDs (#3848)

When producing content, folks often spend time scrubbing or masking
subscription IDs from the output of `azd`. Instead of folks having to spend their time on this, it would be nice if `azd` could do it itself.

This change adds support for setting an environment variable,
`AZD_DEMO_MODE`, which controls if we will show subscription IDs or
not.

In cases where we'd previously show a subscription name and ID (like
the selection box when we ask a user to pick a subscription, or when a
`provision` starts and we print the target subscription and location
information) we now just show the name.

In cases where we'd show a link to the Portal in messages (e.g. during
a deployment when we provide a link into the deployment status) we now
just elide the link since the portal links contain the subscription ID
as part of the URL.

This saves folks creating content a bunch of time and still keeps the
UX very close to what customers actually see (where the subscription
ID is useful information to have.)

Fixes #319
This commit is contained in:
Matt Ellis 2024-05-06 10:07:02 -07:00 коммит произвёл GitHub
Родитель a3e3b7a4ee
Коммит 1ceda20c83
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 57 добавлений и 22 удалений

Просмотреть файл

@ -5,6 +5,8 @@ import (
"fmt"
"io"
"log"
"os"
"strconv"
"strings"
"time"
@ -204,10 +206,17 @@ func (p *ProvisionAction) Run(ctx context.Context) (*actions.ActionResult, error
locationDisplay = location.DisplayName
}
var subscriptionDisplay string
if v, err := strconv.ParseBool(os.Getenv("AZD_DEMO_MODE")); err == nil && v {
subscriptionDisplay = subscription.Name
} else {
subscriptionDisplay = fmt.Sprintf("%s (%s)", subscription.Name, subscription.Id)
}
p.console.MessageUxItem(ctx, &ux.EnvironmentDetails{
Subscription: fmt.Sprintf("%s (%s)", subscription.Name, subscription.Id),
Location: locationDisplay},
)
Subscription: subscriptionDisplay,
Location: locationDisplay,
})
} else {
log.Printf("failed getting subscriptions. Skip displaying sub and location: %v", subErr)

Просмотреть файл

@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"os"
"strconv"
"time"
"github.com/azure/azure-dev/cli/azd/internal/tracing"
@ -28,15 +30,19 @@ func getResourceGroupFollowUp(
subscriptionId := env.GetSubscriptionId()
if resourceGroupName, err := resourceManager.GetResourceGroupName(ctx, subscriptionId, projectConfig); err == nil {
suffix := ":\n" + azurePortalLink(portalUrlBase, subscriptionId, resourceGroupName)
if v, err := strconv.ParseBool(os.Getenv("AZD_DEMO_MODE")); err == nil && v {
suffix = "."
}
defaultFollowUpText := fmt.Sprintf(
"You can view the resources created under the resource group %s in Azure Portal:", resourceGroupName)
"You can view the resources created under the resource group %s in Azure Portal", resourceGroupName)
if whatIf {
defaultFollowUpText = fmt.Sprintf(
"You can view the current resources under the resource group %s in Azure Portal:", resourceGroupName)
"You can view the current resources under the resource group %s in Azure Portal", resourceGroupName)
}
followUp = fmt.Sprintf("%s\n%s",
defaultFollowUpText,
azurePortalLink(portalUrlBase, subscriptionId, resourceGroupName))
followUp = defaultFollowUpText + suffix
}
return followUp

Просмотреть файл

@ -7,7 +7,9 @@ import (
"context"
"fmt"
"log"
"os"
"sort"
"strconv"
"strings"
"time"
@ -58,13 +60,23 @@ func (display *ProvisioningProgressDisplay) ReportProgress(
deploymentUrl := fmt.Sprintf(output.WithLinkFormat("%s\n"), display.target.PortalUrl())
display.console.EnsureBlankLine(ctx)
lines := []string{
"You can view detailed progress in the Azure Portal:",
deploymentUrl,
}
if v, err := strconv.ParseBool(os.Getenv("AZD_DEMO_MODE")); err == nil && v {
lines = []string{
"You can view detailed progress in the Azure Portal.",
"\n",
}
}
display.console.MessageUxItem(
ctx,
&ux.MultilineMessage{
Lines: []string{
"You can view detailed progress in the Azure Portal:",
deploymentUrl,
},
Lines: lines,
},
)
}

Просмотреть файл

@ -6,6 +6,7 @@ import (
"log"
"os"
"slices"
"strconv"
"strings"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
@ -52,7 +53,7 @@ func NewDefaultPrompter(
}
func (p *DefaultPrompter) PromptSubscription(ctx context.Context, msg string) (subscriptionId string, err error) {
subscriptionOptions, defaultSubscription, err := p.getSubscriptionOptions(ctx)
subscriptionOptions, subscriptions, defaultSubscription, err := p.getSubscriptionOptions(ctx)
if err != nil {
return "", err
}
@ -77,9 +78,7 @@ func (p *DefaultPrompter) PromptSubscription(ctx context.Context, msg string) (s
return "", fmt.Errorf("reading subscription id: %w", err)
}
subscriptionSelection := subscriptionOptions[subscriptionSelectionIndex]
subscriptionId = subscriptionSelection[len(subscriptionSelection)-
len("(00000000-0000-0000-0000-000000000000)")+1 : len(subscriptionSelection)-1]
subscriptionId = subscriptions[subscriptionSelectionIndex]
}
if !p.accountManager.HasDefaultSubscription() {
@ -160,10 +159,10 @@ func (p *DefaultPrompter) PromptResourceGroup(ctx context.Context) (string, erro
return name, nil
}
func (p *DefaultPrompter) getSubscriptionOptions(ctx context.Context) ([]string, any, error) {
func (p *DefaultPrompter) getSubscriptionOptions(ctx context.Context) ([]string, []string, any, error) {
subscriptionInfos, err := p.accountManager.GetSubscriptions(ctx)
if err != nil {
return nil, nil, fmt.Errorf("listing accounts: %w", err)
return nil, nil, nil, fmt.Errorf("listing accounts: %w", err)
}
// The default value is based on AZURE_SUBSCRIPTION_ID, falling back to whatever default subscription in
@ -174,15 +173,22 @@ func (p *DefaultPrompter) getSubscriptionOptions(ctx context.Context) ([]string,
}
var subscriptionOptions = make([]string, len(subscriptionInfos))
var subscriptions = make([]string, len(subscriptionInfos))
var defaultSubscription any
for index, info := range subscriptionInfos {
subscriptionOptions[index] = fmt.Sprintf("%2d. %s (%s)", index+1, info.Name, info.Id)
if v, err := strconv.ParseBool(os.Getenv("AZD_DEMO_MODE")); err == nil && v {
subscriptionOptions[index] = fmt.Sprintf("%2d. %s", index+1, info.Name)
} else {
subscriptionOptions[index] = fmt.Sprintf("%2d. %s (%s)", index+1, info.Name, info.Id)
}
subscriptions[index] = info.Id
if info.Id == defaultSubscriptionId {
defaultSubscription = subscriptionOptions[index]
}
}
return subscriptionOptions, defaultSubscription, nil
return subscriptionOptions, subscriptions, defaultSubscription, nil
}

Просмотреть файл

@ -40,10 +40,11 @@ func Test_getSubscriptionOptions(t *testing.T) {
azCli,
cloud.AzurePublic().PortalUrlBase,
).(*DefaultPrompter)
subList, result, err := prompter.getSubscriptionOptions(*mockContext.Context)
subList, subs, result, err := prompter.getSubscriptionOptions(*mockContext.Context)
require.Nil(t, err)
require.EqualValues(t, 1, len(subList))
require.EqualValues(t, 1, len(subs))
require.EqualValues(t, nil, result)
})
@ -82,10 +83,11 @@ func Test_getSubscriptionOptions(t *testing.T) {
azCli,
cloud.AzurePublic().PortalUrlBase,
).(*DefaultPrompter)
subList, result, err := prompter.getSubscriptionOptions(*mockContext.Context)
subList, subs, result, err := prompter.getSubscriptionOptions(*mockContext.Context)
require.Nil(t, err)
require.EqualValues(t, 2, len(subList))
require.EqualValues(t, 2, len(subs))
require.NotNil(t, result)
defSub, ok := result.(string)
require.True(t, ok)