Skip to content

Commit

Permalink
Merge pull request #87 from onepanelio/feat/onepanel.delete
Browse files Browse the repository at this point in the history
feat: cli delete command
  • Loading branch information
Vafilor authored Dec 23, 2020
2 parents a7b7f1e + fe77f35 commit f1a6a55
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 7 deletions.
12 changes: 6 additions & 6 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ var applyCmd = &cobra.Command{
return
}

overlayComponentFirst := filepath.Join("common/application/base")
overlayComponentFirst := filepath.Join("common", "application", "base")
baseOverlayComponent := config.GetOverlayComponent(overlayComponentFirst)
applicationBaseKustomizeTemplate := TemplateFromSimpleOverlayedComponents(baseOverlayComponent)
applicationResult, err := GenerateKustomizeResult(*config, applicationBaseKustomizeTemplate)
Expand All @@ -44,11 +44,11 @@ var applyCmd = &cobra.Command{
return
}

applicationKubernetesYamlFilePath := filepath.Join(".onepanel/application.kubernetes.yaml")
applicationKubernetesYamlFilePath := filepath.Join(".onepanel", "application.kubernetes.yaml")

existsApp, err := files.Exists(applicationKubernetesYamlFilePath)
if err != nil {
log.Printf("Unable to check if file %v exists", applicationKubernetesYamlFilePath)
log.Printf("Unable to check if file '%v' exists", applicationKubernetesYamlFilePath)
return
}

Expand Down Expand Up @@ -77,9 +77,9 @@ var applyCmd = &cobra.Command{

resApp, errResApp, err = applyKubernetesFile(applicationKubernetesYamlFilePath)

log.Printf("%v", resApp)
log.Printf("res: %v", resApp)
if errResApp != "" {
log.Printf("%v", errResApp)
log.Printf("err: %v", errResApp)
}

if err != nil {
Expand Down Expand Up @@ -130,7 +130,7 @@ var applyCmd = &cobra.Command{
return
}

finalKubernetesYamlFilePath := filepath.Join(".onepanel/kubernetes.yaml")
finalKubernetesYamlFilePath := filepath.Join(".onepanel", "kubernetes.yaml")

exists, err := files.Exists(finalKubernetesYamlFilePath)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion cmd/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func GenerateKustomizeResult(config opConfig.Config, kustomizeTemplate template.
}

manifestPath := config.Spec.ManifestsRepo
localManifestsCopyPath := filepath.Join(".onepanel/manifests/cache")
localManifestsCopyPath := filepath.Join(".onepanel", "manifests", "cache")

exists, err := files.Exists(localManifestsCopyPath)
if err != nil {
Expand Down Expand Up @@ -614,6 +614,8 @@ func HumanizeKustomizeError(err error) string {
switch paramsError.ErrorType {
case "missing":
return fmt.Sprintf("%s is missing in your params.yaml", paramsError.Key)
case "parameter":
return fmt.Sprintf("%s can not be '%s', please enter a namespace", paramsError.Key, *paramsError.Value)
case "blank":
return fmt.Sprintf("%s can not be blank, please use a different namespace in your params.yaml", paramsError.Key)
case "reserved":
Expand Down
95 changes: 95 additions & 0 deletions cmd/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package cmd

import (
"fmt"
opConfig "github.com/onepanelio/cli/config"
"github.com/onepanelio/cli/files"
"github.com/onepanelio/cli/util"
"github.com/spf13/cobra"
"path/filepath"
)

var (
// skipConfirmDelete if true, will skip the confirmation prompt of the delete command
skipConfirmDelete bool
)

var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Deletes onepanel cluster resources",
Long: "Delete all onepanel kubernetes cluster resources. Does not delete database unless it is in-cluster.",
Example: "delete",
Run: func(cmd *cobra.Command, args []string) {
if skipConfirmDelete == false {
fmt.Print("Are you sure you want to delete onepanel? ('y' or 'yes' to confirm. Anything else to cancel): ")
userInput := ""
if _, err := fmt.Scanln(&userInput); err != nil {
fmt.Printf("Unable to get response\n")
return
}

if userInput != "y" && userInput != "yes" {
return
}
}

config, err := opConfig.FromFile("config.yaml")
if err != nil {
fmt.Printf("Unable to read configuration file: %v", err.Error())
return
}

paramsYamlFile, err := util.LoadDynamicYamlFromFile(config.Spec.Params)
if err != nil {
fmt.Println("Error parsing configuration file.")
return
}

defaultNamespaceNode := paramsYamlFile.GetValue("application.defaultNamespace")
if defaultNamespaceNode == nil {
fmt.Printf("application.defaultNamespace is missing from your '%s' file\n", config.Spec.Params)
return
}

if defaultNamespaceNode.Value == "default" {
fmt.Println("Unable to delete onepanel in the 'default' namespace")
return
}

if defaultNamespaceNode.Value == "<namespace>" {
fmt.Println("Unable to delete onepanel. No namespace set.")
return
}

filesToDelete := []string{
filepath.Join(".onepanel", "kubernetes.yaml"),
filepath.Join(".onepanel", "application.kubernetes.yaml"),
}

for _, filePath := range filesToDelete {
exists, err := files.Exists(filePath)
if err != nil {
fmt.Printf("Error checking if onepanel files exist: %v\n", err.Error())
return
}

if !exists {
fmt.Printf("'%v' file does not exist. Are you in the directory where you ran 'opctl init'?\n", filePath)
return
}
}

fmt.Printf("Deleting onepanel from your cluster...\n")
for _, filePath := range filesToDelete {
if err := util.KubectlDelete(filePath); err != nil {
fmt.Printf("Unable to delete: %v\n", err.Error())
return
}
}
},
}

func init() {
rootCmd.AddCommand(deleteCmd)
deleteCmd.Flags().BoolVarP(&skipConfirmDelete, "yes", "y", false, "Add this in to skip the confirmation prompt")
}
3 changes: 3 additions & 0 deletions manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ func Validate(manifest *util.DynamicYaml) error {
if defaultNamespace.Value == "" {
return &ParamsError{Key: "application.defaultNamespace", ErrorType: "blank"}
}
if defaultNamespace.Value == "<namespace>" {
return &ParamsError{Key: "application.defaultNamespace", Value: &defaultNamespace.Value, ErrorType: "parameter"}
}
if _, ok := reservedNamespaces[defaultNamespace.Value]; ok {
return &ParamsError{Key: "application.defaultNamespace", Value: &defaultNamespace.Value, ErrorType: "reserved"}
}
Expand Down
61 changes: 61 additions & 0 deletions util/kubectl.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@ import (
"fmt"
opConfig "github.com/onepanelio/cli/config"
"github.com/spf13/cobra"
k8error "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/cli-runtime/pkg/genericclioptions"
_ "k8s.io/client-go/plugin/pkg/client/auth/azure"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"k8s.io/kubectl/pkg/cmd/apply"
k8delete "k8s.io/kubectl/pkg/cmd/delete"
"k8s.io/kubectl/pkg/cmd/get"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
"os"
"runtime"
"strconv"
"strings"
)

func KubectlGet(resource string, resourceName string, namespace string, extraArgs []string, flags map[string]interface{}) (stdout string, stderr string, err error) {
Expand Down Expand Up @@ -125,6 +128,64 @@ func KubectlApply(filePath string) (stdout string, stderr string, err error) {
return
}

// KubectlDelete run's kubectl delete using the input filePath
func KubectlDelete(filePath string) (err error) {
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)

f := cmdutil.NewFactory(matchVersionKubeConfigFlags)
ioStreams := genericclioptions.IOStreams{
In: os.Stdin,
Out: os.Stdout,
ErrOut: os.Stderr,
}
cmd := k8delete.NewCmdDelete(f, ioStreams)

deleteOptions := k8delete.DeleteOptions{IOStreams: ioStreams}
deleteOptions.Filenames = []string{filePath}
err = cmd.Flags().Set("filename", filePath)
if err != nil {
return err
}

if err := deleteOptions.Complete(f, []string{}, cmd); err != nil {
return err
}

if err := deleteOptions.RunDelete(f); err != nil {
errorAggregate, ok := err.(k8error.Aggregate)
if ok {
finalErrors := make([]error, 0)
// Skip any errors that mean "not found"
for _, errItem := range errorAggregate.Errors() {
if strings.Contains(errItem.Error(), "not found") {
continue
}

if strings.Contains(errItem.Error(), "no matches for kind") {
continue
}

if strings.Contains(errItem.Error(), "the server could not find the requested resource") {
continue
}

finalErrors = append(finalErrors, errItem)
}

if len(finalErrors) == 0 {
return nil
}

return k8error.NewAggregate(finalErrors)
}

return err
}

return
}

func validateArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
Expand Down
1 change: 1 addition & 0 deletions util/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func DeploymentStatus(yamlFile *DynamicYaml) (ready bool, err error) {
namespacesToCheck["application-system"] = true
namespacesToCheck["onepanel"] = true
namespacesToCheck["istio-system"] = true
namespacesToCheck["default"] = true

if yamlFile.HasKey("certManager") {
namespacesToCheck["cert-manager"] = true
Expand Down

0 comments on commit f1a6a55

Please sign in to comment.