diff --git a/cli/app/app.go b/cli/app/app.go index e1221ce7..cd30bf3a 100644 --- a/cli/app/app.go +++ b/cli/app/app.go @@ -213,6 +213,62 @@ func Up(c *cli.Context) { kubernetes.CreateObjects(client, objects) } +// Down deletes all deployment, svc. +func Down(c *cli.Context) { + factory := cmdutil.NewFactory(nil) + clientConfig, err := factory.ClientConfig() + if err != nil { + logrus.Fatalf("Failed to access the Kubernetes cluster. Make sure you have a Kubernetes running: %v", err) + } + client := client.NewOrDie(clientConfig) + + inputFile := c.String("file") + dabFile := c.String("bundle") + + komposeObject := kobject.KomposeObject{ + ServiceConfigs: make(map[string]kobject.ServiceConfig), + } + + file := inputFile + if len(dabFile) > 0 { + inputFormat = "bundle" + file = dabFile + } + + opt := kobject.ConvertOptions{} + + validateFlags(opt, false, dabFile, inputFile) + + if c.BoolT("all") { + if len(file) > 0 && file != "docker-compose.yml" { + logrus.Fatalf("Error: --file/--bundle and --all cannot be specified at the same time") + } + fmt.Println("Using flag --all/-a will delete all resources in the kubernetes cluster.") + fmt.Print("Are you sure to continue? (yes/no): ") + if !askForConfirmation() { + return + } + kubernetes.DeleteAll(client) + return + } + + // loader parses input from file into komposeObject. + var l loader.Loader + switch inputFormat { + case "bundle": + l = new(bundle.Bundle) + case "compose": + l = new(compose.Compose) + default: + logrus.Fatalf("Input file format is not supported") + } + komposeObject = l.LoadFile(file) + + for k := range komposeObject.ServiceConfigs { + kubernetes.DeleteObjects(client, k) + } +} + // the objects that we get can be in any order this keeps services first // according to best practice kubernetes services should be created first // http://kubernetes.io/docs/user-guide/config-best-practices/ @@ -230,3 +286,19 @@ func sortServicesFirst(objs *[]runtime.Object) { ret = append(ret, others...) *objs = ret } + +func askForConfirmation() bool { + var response string + _, err := fmt.Scanln(&response) + if err != nil { + logrus.Fatal(err) + } + if response == "yes" { + return true + } else if response == "no" { + return false + } else { + fmt.Println("Please type yes or no and then press enter:") + return askForConfirmation() + } +} diff --git a/cli/command/command.go b/cli/command/command.go index 52e7387d..594a68fc 100644 --- a/cli/command/command.go +++ b/cli/command/command.go @@ -109,72 +109,34 @@ func UpCommand() cli.Command { } } -// PsCommand defines the kompose ps subcommand. -//func PsCommand() cli.Command { -// return cli.Command{ -// Name: "ps", -// Usage: "Get active data in the kubernetes cluster", -// Action: func(c *cli.Context) { -// app.Ps(c) -// }, -// Flags: []cli.Flag{ -// cli.BoolFlag{ -// Name: "service,svc", -// Usage: "Get active services", -// }, -// cli.BoolFlag{ -// Name: "replicationcontroller,rc", -// Usage: "Get active replication controller", -// }, -// }, -// } -//} - -// DeleteCommand defines the kompose delete subcommand. -//func DeleteCommand() cli.Command { -// return cli.Command{ -// Name: "delete", -// Usage: "Remove instantiated services/rc from kubernetes", -// Action: func(c *cli.Context) { -// app.Delete(c) -// }, -// Flags: []cli.Flag{ -// cli.BoolFlag{ -// Name: "replicationcontroller,rc", -// Usage: "Remove active replication controllers", -// }, -// cli.BoolFlag{ -// Name: "service,svc", -// Usage: "Remove active services", -// }, -// cli.StringFlag{ -// Name: "name", -// Usage: "Name of the object to remove", -// }, -// }, -// } -//} - -// ScaleCommand defines the kompose up subcommand. -//func ScaleCommand() cli.Command { -// return cli.Command{ -// Name: "scale", -// Usage: "Globally scale instantiated replication controllers", -// Action: func(c *cli.Context) { -// app.Scale(c) -// }, -// Flags: []cli.Flag{ -// cli.IntFlag{ -// Name: "scale", -// Usage: "New number of replicas", -// }, -// cli.StringFlag{ -// Name: "replicationcontroller,rc", -// Usage: "A specific replication controller to scale", -// }, -// }, -// } -//} +// DownCommand defines the kompose down subcommand. +func DownCommand() cli.Command { + return cli.Command{ + Name: "down", + Usage: "Delete instantiated services/deployments from kubernetes", + Action: func(c *cli.Context) { + app.Down(c) + }, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "file,f", + Usage: fmt.Sprintf("Specify an alternative compose file (default: %s)", app.DefaultComposeFile), + Value: app.DefaultComposeFile, + EnvVar: "COMPOSE_FILE", + }, + cli.StringFlag{ + Name: "bundle,dab", + Usage: "Specify a Distributed Application Bundle (DAB) file", + EnvVar: "DAB_FILE", + }, + cli.BoolFlag{ + Name: "all, a", + Usage: "Delete all resources in default namespace of the kubernetes cluster", + EnvVar: "DOWN_ALL", + }, + }, + } +} // CommonFlags defines the flags that are in common for all subcommands. func CommonFlags() []cli.Flag { diff --git a/cli/main/main.go b/cli/main/main.go index 4d40a7b4..decad4cb 100644 --- a/cli/main/main.go +++ b/cli/main/main.go @@ -38,9 +38,9 @@ func main() { app.Commands = []cli.Command{ command.ConvertCommand(), command.UpCommand(), + command.DownCommand(), // TODO: enable these commands and update docs once we fix them //command.PsCommand(), - //command.DeleteCommand(), //command.ScaleCommand(), } diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go index ff96c7ae..94935255 100644 --- a/pkg/transformer/kubernetes/kubernetes.go +++ b/pkg/transformer/kubernetes/kubernetes.go @@ -294,3 +294,75 @@ func CreateObjects(client *client.Client, objects []runtime.Object) { } fmt.Println("\nYour application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods' for details.") } + +func DeleteObjects(client *client.Client, name string) { + err := client.Services(api.NamespaceDefault).Delete(name) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting service: %s", err, name) + } + logrus.Infof("Successfully deleted service: %s", name) + + err = client.Deployments(api.NamespaceDefault).Delete(name, nil) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting deployment: %s", err, name) + } + logrus.Infof("Successfully deleted deployment: %s", name) +} + +func DeleteAll(client *client.Client) { + //delete all svc + listOpts := api.ListOptions{} + svcs, err := client.Services(api.NamespaceDefault).List(listOpts) + if err != nil { + logrus.Fatalf("Error: '%v' while listing services in the cluster", err) + } + for _, svc := range svcs.Items { + if svc.Name == "kubernetes" { + continue + } + err = client.Services(api.NamespaceDefault).Delete(svc.Name) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting service: %s", err, svc.Name) + } + logrus.Infof("Successfully deleted service: %s", svc.Name) + } + + //delete all deployment + deployments, err := client.Deployments(api.NamespaceDefault).List(listOpts) + if err != nil { + logrus.Fatalf("Error: '%v' while listing deployments in the cluster", err) + } + for _, deployment := range deployments.Items { + err = client.Deployments(api.NamespaceDefault).Delete(deployment.Name, nil) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting deployment: %s", err, deployment.Name) + } + logrus.Infof("Successfully deleted deployment: %s", deployment.Name) + } + + //delete all daemonset + daemons, err := client.DaemonSets(api.NamespaceDefault).List(listOpts) + if err != nil { + logrus.Fatalf("Error: '%v' while listing daemonsets in the cluster", err) + } + for _, daemon := range daemons.Items { + err = client.DaemonSets(api.NamespaceDefault).Delete(daemon.Name) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting daemonset: %s", err, daemon.Name) + } + logrus.Infof("Successfully deleted daemonset: %s", daemon.Name) + } + + //delete all rc + rcs, err := client.ReplicationControllers(api.NamespaceDefault).List(listOpts) + if err != nil { + logrus.Fatalf("Error: '%v' while listing replication controllers in the cluster", err) + } + for _, rc := range rcs.Items { + err = client.ReplicationControllers(api.NamespaceDefault).Delete(rc.Name) + if err != nil { + logrus.Fatalf("Error: '%v' while deleting replication controller: %s", err, rc.Name) + } + logrus.Infof("Successfully deleted replication controller: %s", rc.Name) + } +}