Add abra app remove command #43
|
@ -1,7 +1,19 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"coopcloud.tech/abra/cli/internal"
|
||||
"coopcloud.tech/abra/client"
|
||||
"coopcloud.tech/abra/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"
|
||||
)
|
||||
|
||||
|
@ -16,9 +28,114 @@ var VolumesFlag = &cli.BoolFlag{
|
|||
}
|
||||
|
||||
var appRemoveCommand = &cli.Command{
|
||||
Name: "remove",
|
||||
Name: "remove",
|
||||
knoflook marked this conversation as resolved
Outdated
|
||||
Aliases: []string{"rm", "delete"},
|
||||
Flags: []cli.Flag{
|
||||
VolumesFlag,
|
||||
internal.SecretsFlag,
|
||||
internal.ForceFlag,
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
appName := c.Args().First()
|
||||
if appName == "" {
|
||||
internal.ShowSubcommandHelpAndError(c, errors.New("No app name provided!"))
|
||||
}
|
||||
if !internal.Force {
|
||||
response := false
|
||||
prompt := &survey.Confirm{
|
||||
Message: fmt.Sprintf("About to delete %s, are you sure", appName),
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
We haven't discussed this but the existing convention that I see is that we don't add comments to code to explain what it is doing unless it is doing something strange or difficult. Otherwise, we comment to explain why we're doing something (context, not what it is doing). The issue is, that when the code changes, you might forget to change the comment and then the next person might be caught reading the comment which describes code that doesn'te exist anymore. I would say have a look around the rest of the codebase at comment usage and perhaps remove the obvious ones in this function. For example the We haven't discussed this but the existing convention that I see is that we don't add comments to code to explain what it is doing unless it is doing something strange or difficult. Otherwise, we comment to explain why we're doing something (context, not what it is doing).
The issue is, that when the code changes, you might forget to change the comment and then the next person might be caught reading the comment which describes code that doesn'te exist anymore. I would say have a look around the rest of the codebase at comment usage and perhaps remove the obvious ones in this function.
For example the `// we have to map the names to ID's` comment is a good one, I'd keep that.
|
||||
}
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`appName` (e.g. [host](https://git.coopcloud.tech/coop-cloud/go-abra/src/branch/main/cli/recipe/recipe.go#L189))
|
||||
survey.AskOne(prompt, &response)
|
||||
if !response {
|
||||
return errors.New("User aborted app removal")
|
||||
}
|
||||
}
|
||||
appFiles, err := config.LoadAppFiles("")
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`Message: fmt.Sprintf("About to delete %s, are you sure?", appName)`
|
||||
}
|
||||
appPath := appFiles[appName].Path
|
||||
fmt.Println(appFiles)
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
```golang
if !response {
logrus.Fatal(errors.New("User aborted app removal"))
}
```
|
||||
host := appFiles[appName].Server
|
||||
ctx := context.Background()
|
||||
cl, err := client.NewClientWithContext(host)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
decentral1se marked this conversation as resolved
Outdated
decentral1se
commented
`appFiles, err := config.LoadAppFiles()`
knoflook
commented
Can't do it that way, if you remove "" LoadAppFiles returns an empty map[] Can't do it that way, if you remove "" LoadAppFiles returns an empty map[]
|
||||
}
|
||||
err = os.Remove(appPath)
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`logrus.Fatal(err)`
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`appPath := AppFiles[appName].Path`
|
||||
} else {
|
||||
logrus.Info(fmt.Sprintf("File: %s removed", appPath))
|
||||
}
|
||||
|
||||
fs := filters.NewArgs()
|
||||
fs.Add("name", appName)
|
||||
secretList, err := cl.SecretList(ctx, types.SecretListOptions{Filters: fs})
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
knoflook marked this conversation as resolved
decentral1se
commented
```golang
if err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("File: %s removed", appPath))
```
|
||||
secrets := make(map[string]string)
|
||||
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)
|
||||
}
|
||||
secretNamesToRemove := []string{}
|
||||
|
||||
if internal.Force {
|
||||
secretNamesToRemove = secretNames
|
||||
} else {
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`logrus.Fatal(err)`
|
||||
secretsPrompt := &survey.MultiSelect{
|
||||
Message: "Which secrets do you want to remove?",
|
||||
Options: secretNames,
|
||||
Default: secretNames,
|
||||
}
|
||||
survey.AskOne(secretsPrompt, &secretNamesToRemove)
|
||||
}
|
||||
|
||||
for _, name := range secretNamesToRemove {
|
||||
err := cl.SecretRemove(ctx, secrets[name])
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
} else {
|
||||
logrus.Info(fmt.Sprintf("Secret: %s removed", name))
|
||||
}
|
||||
}
|
||||
|
||||
volumeListOKBody, err := cl.VolumeList(ctx, fs)
|
||||
volumeList := volumeListOKBody.Volumes
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
vols := []string{}
|
||||
for _, vol := range volumeList {
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
Let's remove that 🙃 Let's remove that 🙃
|
||||
vols = append(vols, vol.Name)
|
||||
}
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
```golang
if err != nil {
logrus.Fatal(err)
}
logrus.Info(fmt.Sprintf("Secret: %s removed", name))
```
|
||||
|
||||
if Volumes {
|
||||
removeVols := []string{}
|
||||
if internal.Force {
|
||||
removeVols = vols
|
||||
} else {
|
||||
volumesPrompt := &survey.MultiSelect{
|
||||
Message: "Which volumes do you want to remove?",
|
||||
Options: vols,
|
||||
Default: vols,
|
||||
}
|
||||
knoflook marked this conversation as resolved
decentral1se
commented
`logrus.Fatal(err)`
|
||||
survey.AskOne(volumesPrompt, &removeVols)
|
||||
}
|
||||
for _, vol := range removeVols {
|
||||
err := cl.VolumeRemove(ctx, vol, internal.Force) // last argument is for force removing
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
} else {
|
||||
knoflook marked this conversation as resolved
Outdated
decentral1se
commented
`if Volumes {`
|
||||
logrus.Info("Volume " + vol + " removed")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logrus.Info("No volumes were removed. Volumes left: " + strings.Join(vols, ", "))
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
|
|
@ -42,3 +42,12 @@ var ContextFlag = &cli.StringFlag{
|
|||
Aliases: []string{"c"},
|
||||
Destination: &Context,
|
||||
}
|
||||
|
||||
var Force bool
|
||||
|
||||
var ForceFlag = &cli.BoolFlag{
|
||||
Name: "force",
|
||||
Value: false,
|
||||
Aliases: []string{"f"},
|
||||
Destination: &Force,
|
||||
}
|
||||
|
|
This is a general flag we'll add to other sub-commands, it can live in cli/internal/common.go?