/
down.go
171 lines (152 loc) · 5.32 KB
/
down.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package cmd
import (
"context"
"fmt"
"time"
"github.com/azure/azure-dev/cli/azd/cmd/actions"
"github.com/azure/azure-dev/cli/azd/internal"
"github.com/azure/azure-dev/cli/azd/pkg/account"
"github.com/azure/azure-dev/cli/azd/pkg/alpha"
"github.com/azure/azure-dev/cli/azd/pkg/environment"
"github.com/azure/azure-dev/cli/azd/pkg/environment/azdcontext"
"github.com/azure/azure-dev/cli/azd/pkg/exec"
"github.com/azure/azure-dev/cli/azd/pkg/infra/provisioning"
"github.com/azure/azure-dev/cli/azd/pkg/input"
"github.com/azure/azure-dev/cli/azd/pkg/output"
"github.com/azure/azure-dev/cli/azd/pkg/output/ux"
"github.com/azure/azure-dev/cli/azd/pkg/project"
"github.com/azure/azure-dev/cli/azd/pkg/tools/azcli"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type downFlags struct {
forceDelete bool
purgeDelete bool
global *internal.GlobalCommandOptions
envFlag
}
func (i *downFlags) Bind(local *pflag.FlagSet, global *internal.GlobalCommandOptions) {
local.BoolVar(&i.forceDelete, "force", false, "Does not require confirmation before it deletes resources.")
local.BoolVar(
&i.purgeDelete,
"purge",
false,
//nolint:lll
"Does not require confirmation before it permanently deletes resources that are soft-deleted by default (for example, key vaults).",
)
i.envFlag.Bind(local, global)
i.global = global
}
func newDownFlags(cmd *cobra.Command, global *internal.GlobalCommandOptions) *downFlags {
flags := &downFlags{}
flags.Bind(cmd.Flags(), global)
return flags
}
func newDownCmd() *cobra.Command {
return &cobra.Command{
Use: "down",
Short: "Delete Azure resources for an application.",
}
}
type downAction struct {
flags *downFlags
accountManager account.Manager
azCli azcli.AzCli
azdCtx *azdcontext.AzdContext
env *environment.Environment
console input.Console
commandRunner exec.CommandRunner
projectConfig *project.ProjectConfig
userProfileService *azcli.UserProfileService
subResolver account.SubscriptionTenantResolver
alphaFeatureManager *alpha.FeatureManager
}
func newDownAction(
flags *downFlags,
accountManager account.Manager,
azCli azcli.AzCli,
azdCtx *azdcontext.AzdContext,
env *environment.Environment,
projectConfig *project.ProjectConfig,
console input.Console,
commandRunner exec.CommandRunner,
userProfileService *azcli.UserProfileService,
subResolver account.SubscriptionTenantResolver,
alphaFeatureManager *alpha.FeatureManager,
) actions.Action {
return &downAction{
flags: flags,
accountManager: accountManager,
azCli: azCli,
azdCtx: azdCtx,
env: env,
console: console,
commandRunner: commandRunner,
projectConfig: projectConfig,
userProfileService: userProfileService,
subResolver: subResolver,
alphaFeatureManager: alphaFeatureManager,
}
}
func (a *downAction) Run(ctx context.Context) (*actions.ActionResult, error) {
// silent manager for running Plan()
infraManager, err := createProvisioningManager(ctx, a, a.console)
if err != nil {
return nil, fmt.Errorf("creating provisioning manager: %w", err)
}
// Command title
a.console.MessageUxItem(ctx, &ux.MessageTitle{
Title: "Deleting all resources and deployed code on Azure (azd down)",
TitleNote: "Local application code is not deleted when running 'azd down'.",
})
startTime := time.Now()
destroyOptions := provisioning.NewDestroyOptions(a.flags.forceDelete, a.flags.purgeDelete)
destroyResult, err := infraManager.Destroy(ctx, destroyOptions)
if err != nil {
return nil, fmt.Errorf("deleting infrastructure: %w", err)
}
// Remove any outputs from the template from the environment since destroying the infrastructure
// invalidated them all.
for outputName := range destroyResult.Outputs {
a.env.DotenvDelete(outputName)
}
if err := a.env.Save(); err != nil {
return nil, fmt.Errorf("saving environment: %w", err)
}
return &actions.ActionResult{
Message: &actions.ResultMessage{
Header: fmt.Sprintf("Your application was removed from Azure in %s.", ux.DurationAsText(time.Since(startTime))),
},
}, nil
}
func createProvisioningManager(ctx context.Context, a *downAction, console input.Console) (*provisioning.Manager, error) {
infraManager, err := provisioning.NewManager(
ctx,
a.env,
a.projectConfig.Path,
a.projectConfig.Infra,
a.console.IsUnformatted(),
a.azCli,
console,
a.commandRunner,
a.accountManager,
a.userProfileService,
a.subResolver,
a.alphaFeatureManager,
)
return infraManager, err
}
func getCmdDownHelpDescription(*cobra.Command) string {
return generateCmdHelpDescription(fmt.Sprintf(
"Delete Azure resources for an application. Running %s will not delete application"+
" files on your local machine.", output.WithHighLightFormat("azd down")), nil)
}
func getCmdDownHelpFooter(*cobra.Command) string {
return generateCmdHelpSamplesBlock(map[string]string{
"Delete all resources for an application." +
" You will be prompted to confirm your decision.": output.WithHighLightFormat("azd down"),
"Forcibly delete all applications resources without confirmation.": output.WithHighLightFormat("azd down --force"),
"Permanently delete resources that are soft-deleted by default," +
" without confirmation.": output.WithHighLightFormat("azd down --purge"),
})
}