Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Modify project destroy to require -p flag and delete projects created in UI without data source #4212

Merged
merged 12 commits into from
Nov 29, 2022
7 changes: 7 additions & 0 deletions .changelog/4212.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:improvement
cli: `project destroy` requires the `-project` or `-p` flag regardless of where it's run.
```

```release-note:bug
cli: `project destroy` now successfully destroys a project created in the UI without a remote source or local hcl file.
```
40 changes: 27 additions & 13 deletions internal/cli/project_destroy.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package cli

import (
"strings"

"github.com/hashicorp/waypoint-plugin-sdk/terminal"
"github.com/hashicorp/waypoint/internal/clierrors"
"github.com/hashicorp/waypoint/internal/pkg/flag"
pb "github.com/hashicorp/waypoint/pkg/server/gen"
"strings"
)

type ProjectDestroyCommand struct {
Expand All @@ -24,20 +25,21 @@ func (c *ProjectDestroyCommand) Run(args []string) int {
return 1
}

if c.project == nil {
c.ui.Output("The -project flag must be set.", terminal.WithErrorStyle())
if c.flagProject == "" {
c.ui.Output("Must explicitly set -project (-p) flag to destroy project.\n %s", c.Flags().Help(), terminal.WithErrorStyle())
return 1
}

// Get the project we're destroying
// Verify the project we're destroying exists
project, err := c.project.Client().GetProject(c.Ctx, &pb.GetProjectRequest{
Project: c.project.Ref(),
})
if err != nil {
c.ui.Output("Project %q not found.", c.project.Ref().Project, terminal.WithErrorStyle())
return 1
}

// Confirmation is required for destroying a project &/or its resources
// Confirmation required without `-auto-approve` flag
if !c.confirm {
proceed, err := c.ui.Input(&terminal.Input{
Prompt: "Do you really want to destroy project \"" + project.Project.Name + "\" and its resources? Only 'yes' will be accepted to approve: ",
Expand All @@ -56,12 +58,21 @@ func (c *ProjectDestroyCommand) Run(args []string) int {
return 1
}
}
_, err = c.project.DestroyProject(c.Ctx, &pb.Job_DestroyProjectOp{
Project: &pb.Ref_Project{Project: project.Project.Name},
SkipDestroyResources: c.skipDestroyResources,
})

// If project has a remote data source, queue destroy operation.
// Otherwise, directly call server API to delete from the database.
if project.Project.DataSource == nil {
_, err = c.project.Client().DestroyProject(c.Ctx, &pb.DestroyProjectRequest{
Project: c.project.Ref(),
})
} else {
_, err = c.project.DestroyProject(c.Ctx, &pb.Job_DestroyProjectOp{
Project: &pb.Ref_Project{Project: project.Project.Name},
SkipDestroyResources: c.skipDestroyResources,
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This confused me at first - I wasn't sure what the difference was between these two DestroyProject funcs. Maybe a quick doc comment note about how one is a client func that queues a DestroyProject operation, and the other is an API call to the server that deletes the projects record from the db with no job?

}
if err != nil {
c.ui.Output("Error destroying project: %s", err.Error(), terminal.WithErrorStyle())
c.ui.Output("Error destroying project %q: %s", project.Project.Name, err.Error(), terminal.WithErrorStyle())
return 1
}
c.ui.Output("Project %q destroyed!", project.Project.Name, terminal.WithSuccessStyle())
Expand Down Expand Up @@ -95,12 +106,15 @@ func (c *ProjectDestroyCommand) Synopsis() string {

func (c *ProjectDestroyCommand) Help() string {
return formatHelp(`
Usage: waypoint project destroy [options]
Usage: waypoint project destroy [options] -p <project>

Delete the project and all resources created for all apps in the project, within
the platform each app was deployed to.

You can optionally skip destroying the resources by setting
-skip-destroy-resources to true.
You must explicitly specify the project to destroy with the -project or -p flag.

You can skip destroying app resources with the -skip-destroy-resources flag.

You can skip the manual confirmation prompt with the -auto-approve flag.
` + c.Flags().Help())
}
2 changes: 1 addition & 1 deletion internal/runner/accept.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (r *Runner) accept(ctx context.Context, id string) error {
// Grab this lock before updating canceled. You don't
// need to have this lock to touch canceled (we use atomic ops)
// but it is used when the streamCancel is being reset so that
// we don't set it up and race with cancelation.
// we don't set it up and race with cancellation.
streamCtxLock.Lock()
defer streamCtxLock.Unlock()

Expand Down
9 changes: 6 additions & 3 deletions website/content/commands/project-destroy.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ Delete the specified project and optionally destroy its resources.

## Usage

Usage: `waypoint project destroy [options]`
Usage: `waypoint project destroy [options] -p <project>`

Delete the project and all resources created for all apps in the project, within
the platform each app was deployed to.

You can optionally skip destroying the resources by setting
-skip-destroy-resources to true.
You must explicitly specify the project to destroy with the -project or -p flag.

You can skip destroying app resources with the -skip-destroy-resources flag.

You can skip the manual confirmation prompt with the -auto-approve flag.

#### Global Options

Expand Down