0
0
forked from toolshed/abra
Files
.chglog
.gitea
cli
app
app.go
backup.go
check.go
config.go
cp.go
deploy.go
list.go
logs.go
new.go
ps.go
remove.go
restore.go
rollback.go
run.go
secret.go
undeploy.go
upgrade.go
version.go
volume.go
catalogue
formatter
internal
recipe
server
cli.go
upgrade.go
version.go
cmd
pkg
scripts
tests
.drone.yml
.envrc.sample
.gitignore
.goreleaser.yml
Makefile
README.md
go.mod
go.sum
abra/cli/app/remove.go

169 lines
3.9 KiB
Go

package app
import (
"fmt"
"os"
"coopcloud.tech/abra/cli/internal"
"coopcloud.tech/abra/pkg/client"
"coopcloud.tech/abra/pkg/config"
"github.com/AlecAivazis/survey/v2"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
// Volumes stores the variable from VolumesFlag
var Volumes bool
// VolumesFlag is used to specify if volumes should be deleted when deleting an app
var VolumesFlag = &cli.BoolFlag{
Name: "volumes",
Value: false,
Destination: &Volumes,
}
var appRemoveCommand = &cli.Command{
Name: "remove",
Usage: "Remove an already undeployed app",
Aliases: []string{"rm"},
Flags: []cli.Flag{
VolumesFlag,
internal.ForceFlag,
},
Action: func(c *cli.Context) error {
app := internal.ValidateApp(c)
if !internal.Force {
response := false
prompt := &survey.Confirm{
Message: fmt.Sprintf("about to delete %s, are you sure?", app.Name),
}
if err := survey.AskOne(prompt, &response); err != nil {
logrus.Fatal(err)
}
if !response {
logrus.Fatal("user aborted app removal")
}
}
appFiles, err := config.LoadAppFiles("")
if err != nil {
logrus.Fatal(err)
}
cl, err := client.New(app.Server)
if err != nil {
logrus.Fatal(err)
}
if !internal.Force {
// FIXME: only query for app we are interested in, not all of them!
statuses, err := config.GetAppStatuses(appFiles)
if err != nil {
logrus.Fatal(err)
}
if statuses[app.Name]["status"] == "deployed" {
logrus.Fatalf("'%s' is still deployed. Run \"abra app %s undeploy\" or pass --force", app.Name, app.Name)
}
}
fs := filters.NewArgs()
fs.Add("name", app.Name)
secretList, err := cl.SecretList(c.Context, types.SecretListOptions{Filters: fs})
if err != nil {
logrus.Fatal(err)
}
secrets := make(map[string]string)
var secretNames []string
for _, cont := range secretList {
secrets[cont.Spec.Annotations.Name] = cont.ID // we have to map the names to ID's
secretNames = append(secretNames, cont.Spec.Annotations.Name)
}
if len(secrets) > 0 {
var secretNamesToRemove []string
if !internal.Force {
secretsPrompt := &survey.MultiSelect{
Message: "which secrets do you want to remove?",
Options: secretNames,
Default: secretNames,
}
if err := survey.AskOne(secretsPrompt, &secretNamesToRemove); err != nil {
logrus.Fatal(err)
}
}
for _, name := range secretNamesToRemove {
err := cl.SecretRemove(c.Context, secrets[name])
if err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("secret: %s removed", name))
}
} else {
logrus.Info("no secrets to remove")
}
volumeListOKBody, err := cl.VolumeList(c.Context, fs)
volumeList := volumeListOKBody.Volumes
if err != nil {
logrus.Fatal(err)
}
var vols []string
for _, vol := range volumeList {
vols = append(vols, vol.Name)
}
if len(vols) > 0 {
if Volumes {
var removeVols []string
if !internal.Force {
volumesPrompt := &survey.MultiSelect{
Message: "which volumes do you want to remove?",
Options: vols,
Default: vols,
}
if err := survey.AskOne(volumesPrompt, &removeVols); err != nil {
logrus.Fatal(err)
}
}
for _, vol := range removeVols {
err := cl.VolumeRemove(c.Context, vol, internal.Force) // last argument is for force removing
if err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("volume %s removed", vol))
}
} else {
logrus.Info("no volumes were removed")
}
} else {
logrus.Info("no volumes to remove")
}
err = os.Remove(app.Path)
if err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("file: %s removed", app.Path))
return nil
},
BashComplete: func(c *cli.Context) {
appNames, err := config.GetAppNames()
if err != nil {
logrus.Warn(err)
}
if c.NArg() > 0 {
return
}
for _, a := range appNames {
fmt.Println(a)
}
},
}