Skip to content

Commit

Permalink
fix: improve liqoctl uninstall error message
Browse files Browse the repository at this point in the history
this patch improves the liqoctl uninstall error message when the
pre-uninstall checks fail, by suggesting the user which command has to
be used to unpeer a cluster.
  • Loading branch information
claudiolor authored and fra98 committed Nov 28, 2024
1 parent 4e5704f commit b5ca503
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
20 changes: 20 additions & 0 deletions pkg/liqoctl/uninstall/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"context"
"errors"
"fmt"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -67,6 +68,25 @@ func (o *Options) Run(ctx context.Context) error {
s := o.Printer.StartSpinner("Running pre-uninstall checks")
if err := utils.PreUninstall(ctx, o.CRClient); err != nil {
s.Fail("Pre-uninstall checks failed: ", output.PrettyErr(err))
var uninstallErr utils.UninstallError
if errors.As(err, &uninstallErr) {
errorTypes := uninstallErr.GetErrorTypes()
if slices.Contains(errorTypes, utils.PendingActivePeerings) {
o.Printer.Error.Printfln(
"You must remove all the active peerings with other clusters before uninstalling Liqo.\n" +
"You can disable the active peerings via the 'liqoctl unpeer' command.\n" +
"Check 'liqoctl unpeer --help' for further information.",
)
}

if slices.Contains(errorTypes, utils.PendingOffloadedNamespaces) {
o.Printer.Error.Printfln(
"You must remove all the offloaded namespaces before uninstalling Liqo.\n" +
"You can disable the namespace offloading 'liqoctl unoffload' command.\n" +
"Check 'liqoctl unoffload --help' for further information.\n",
)
}
}
return err
}
s.Success("Pre-uninstall checks passed")
Expand Down
50 changes: 42 additions & 8 deletions pkg/utils/preuninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package utils
import (
"context"
"fmt"
"maps"
"slices"

"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -32,6 +33,18 @@ import (
ipamutils "github.com/liqotech/liqo/pkg/utils/ipam"
)

// UninstallErrorType is the type of uninstall error.
type UninstallErrorType string

const (
// GenericUninstallError is an error related to resources that needs to be removed.
GenericUninstallError = "generic"
// PendingActivePeerings is an error related peerings still active.
PendingActivePeerings = "pendingActivePeerings"
// PendingOffloadedNamespaces is an error related to namespaces still offloaded.
PendingOffloadedNamespaces = "pendingOffloadedNamespaces"
)

type errorMap struct {
networking []string
authentication []string
Expand All @@ -50,53 +63,74 @@ func newErrorMap() errorMap {
}
}

// UninstallError is an error type returned when there are errors during the uninstall process.
type UninstallError struct {
errorTypes []UninstallErrorType
message string
}

// GetErrorTypes returns the type of uninstall error.
func (ue UninstallError) GetErrorTypes() []UninstallErrorType {
return ue.errorTypes
}

// Error returns the error message.
func (ue UninstallError) Error() string {
return ue.message
}

func (em *errorMap) getError() error {
str := ""
hasErr := false
errorTypes := map[UninstallErrorType]bool{}

if len(em.networking) > 0 {
str += "\ndisable networking for clusters:\n"
for _, fc := range em.networking {
str += fmt.Sprintf("- %s\n", fc)
}
hasErr = true
errorTypes[PendingActivePeerings] = true
}

if len(em.authentication) > 0 {
str += "\ndisable authentication for clusters:\n"
for i := range em.authentication {
str += fmt.Sprintf("- %s\n", em.authentication[i])
}
hasErr = true
errorTypes[PendingActivePeerings] = true
}

if len(em.offloading) > 0 {
str += "\ndisable offloading for clusters:\n"
for _, fc := range em.offloading {
str += fmt.Sprintf("- %s\n", fc)
}
hasErr = true
errorTypes[PendingActivePeerings] = true
}

if len(em.namespaces) > 0 {
str += "\nunoffload the following namespaces:\n"
for i := range em.namespaces {
str += fmt.Sprintf("- %s\n", em.namespaces[i])
}
hasErr = true
errorTypes[PendingOffloadedNamespaces] = true
}

if len(em.generic) > 0 {
str += "\nremove the following resources:\n"
for i := range em.generic {
str += fmt.Sprintf("- %s\n", em.generic[i])
}
hasErr = true
errorTypes[GenericUninstallError] = true
}

if hasErr {
return fmt.Errorf("you should:\n%s", str)
if len(errorTypes) > 0 {
msg := fmt.Sprintf("you should:\n%s", str)
return UninstallError{
errorTypes: slices.Collect(maps.Keys(errorTypes)),
message: msg,
}
}

return nil
}

Expand Down

0 comments on commit b5ca503

Please sign in to comment.