Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add CLI option --format to disconnect command #108

Merged
merged 3 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 154 additions & 60 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,18 +298,20 @@ func connectAction(ctx *cli.Context) error {
message: fmt.Errorf("cannot connect to Red Hat Subscription Management: %w",
err)}
fmt.Printf(
uiSettings.iconError + " Cannot connect to Red Hat Subscription Management\n",
"%v Cannot connect to Red Hat Subscription Management\n",
uiSettings.iconError,
)
} else {
fmt.Printf(uiSettings.iconOK + " " + returnedMsg + "\n")
fmt.Printf("%v %v\n", uiSettings.iconOK, returnedMsg)
}
durations["rhsm"] = time.Since(start)

/* 2. Register insights-client */
if errors, exist := errorMessages["rhsm"]; exist {
if errors.level == log.LevelError {
fmt.Printf(
uiSettings.iconError + " Skipping connection to Red Hat Insights\n",
"%v Skipping connection to Red Hat Insights\n",
uiSettings.iconError,
)
}
} else {
Expand All @@ -320,9 +322,9 @@ func connectAction(ctx *cli.Context) error {
level: log.LevelError,
message: fmt.Errorf("cannot connect to Red Hat Insights: %w",
err)}
fmt.Printf(uiSettings.iconError + " Cannot connect to Red Hat Insights\n")
fmt.Printf("%v Cannot connect to Red Hat Insights\n", uiSettings.iconError)
} else {
fmt.Printf(uiSettings.iconOK + " Connected to Red Hat Insights\n")
fmt.Printf("%v Connected to Red Hat Insights\n", uiSettings.iconOK)
}
durations["insights"] = time.Since(start)
}
Expand All @@ -331,7 +333,8 @@ func connectAction(ctx *cli.Context) error {
if errors, exist := errorMessages["rhsm"]; exist {
if errors.level == log.LevelError {
fmt.Printf(
uiSettings.iconError+" Skipping activation of %v service\n",
"%v Skipping activation of %v service\n",
uiSettings.iconError,
ServiceName,
)
}
Expand All @@ -344,9 +347,9 @@ func connectAction(ctx *cli.Context) error {
level: log.LevelError,
message: fmt.Errorf("cannot activate %s service: %w",
ServiceName, err)}
fmt.Printf(uiSettings.iconError+" Cannot activate the %v service\n", ServiceName)
fmt.Printf("%v Cannot activate the %v service\n", uiSettings.iconError, ServiceName)
} else {
fmt.Printf(uiSettings.iconOK+" Activated the %v service\n", ServiceName)
fmt.Printf("%v Activated the %v service\n", uiSettings.iconOK, ServiceName)
}
durations[ServiceName] = time.Since(start)
}
Expand Down Expand Up @@ -379,7 +382,7 @@ func connectAction(ctx *cli.Context) error {
message: fmt.Errorf("cannot get the user profile: %w",
err)}
} else {
fmt.Printf(uiSettings.iconInfo + " Enabled console.redhat.com services: ")
fmt.Printf("%v Enabled console.redhat.com services: ", uiSettings.iconInfo)
showConfProfile(&profile)
fmt.Printf("\n")
}
Expand All @@ -401,49 +404,146 @@ func connectAction(ctx *cli.Context) error {
return nil
}

// disconnectAction tries to stop rhscd service, disconnect from Red Hat Insights and finally
// it unregister system from Red Hat Subscription Management
// setupFormatOption ensures the user has supplied a correct `--format` flag
// and set values in uiSettings, when JSON format is used.
func setupFormatOption(ctx *cli.Context) error {
// This is run after the `app.Before()` has been run,
// the uiSettings is already set up for us to modify.
format := ctx.String("format")
switch format {
case "":
return nil
case "json":
uiSettings.isMachineReadable = true
uiSettings.isRich = false
return nil
default:
err := fmt.Errorf(
"unsupported format: %s (supported formats: %s)",
format,
`"json"`,
)
return cli.Exit(err, 1)
}
}

// DisconnectResult is structure holding information about result of
// disconnect command. The result could be printed in machine-readable format.
type DisconnectResult struct {
subpop marked this conversation as resolved.
Show resolved Hide resolved
Hostname string `json:"hostname"`
HostnameError string `json:"hostname_error,omitempty"`
UID int `json:"uid"`
UIDError string `json:"uid_error,omitempty"`
RHSMDisconnected bool `json:"rhsm_disconnected"`
RHSMDisconnectedError string `json:"rhsm_disconnect_error,omitempty"`
InsightsDisconnected bool `json:"insights_disconnected"`
InsightsDisconnectedError string `json:"insights_disconnected_error,omitempty"`
YggdrasilStopped bool `json:"yggdrasil_stopped"`
YggdrasilStoppedError string `json:"yggdrasil_stopped_error,omitempty"`
format string
}

// Error implement error interface for structure DisconnectResult
// It is used for printing DisconnectResult by cli.Exit()
func (disconnectResult DisconnectResult) Error() string {
var result string
switch disconnectResult.format {
case "json":
data, err := json.MarshalIndent(disconnectResult, "", " ")
if err != nil {
return err.Error()
}
result = string(data)
default:
result = "error: unsupported document format: " + disconnectResult.format
}
return result
}

// beforeDisconnectAction ensures the used has supplied a correct `--format` flag
func beforeDisconnectAction(ctx *cli.Context) error {
return setupFormatOption(ctx)
}

// interactivePrintf is method for printing human-readable output. It suppresses output, when
// machine-readable format is used.
func interactivePrintf(format string, a ...interface{}) {
if !uiSettings.isMachineReadable {
fmt.Printf(format, a...)
}
}

// disconnectAction tries to stop (yggdrasil) rhcd service, disconnect from Red Hat Insights,
// and finally it unregisters system from Red Hat Subscription Management
func disconnectAction(ctx *cli.Context) error {
var disconnectResult DisconnectResult
disconnectResult.format = ctx.String("format")

uid := os.Getuid()
if uid != 0 {
return cli.Exit(fmt.Errorf("error: non-root user cannot disconnect system"), 1)
errMsg := "non-root user cannot disconnect system"
exitCode := 1
if uiSettings.isMachineReadable {
disconnectResult.UID = uid
disconnectResult.UIDError = errMsg
return cli.Exit(disconnectResult, exitCode)
} else {
return cli.Exit(fmt.Errorf("error: %s", errMsg), exitCode)
}
}

var start time.Time
durations := make(map[string]time.Duration)
errorMessages := make(map[string]LogMessage)
hostname, err := os.Hostname()
if uiSettings.isMachineReadable {
disconnectResult.Hostname = hostname
}
if err != nil {
return cli.Exit(err, 1)
exitCode := 1
if uiSettings.isMachineReadable {
disconnectResult.HostnameError = err.Error()
return cli.Exit(disconnectResult, exitCode)
} else {
return cli.Exit(err, exitCode)
}
}
fmt.Printf("Disconnecting %v from %v.\nThis might take a few seconds.\n\n", hostname, Provider)

interactivePrintf("Disconnecting %v from %v.\nThis might take a few seconds.\n\n", hostname, Provider)

var start time.Time
durations := make(map[string]time.Duration)
errorMessages := make(map[string]LogMessage)

/* 1. Deactivate yggdrasil (rhcd) service */
start = time.Now()
progressMessage := fmt.Sprintf(" Deactivating the %v service", ServiceName)
err = showProgress(progressMessage, deactivateService)
if err != nil {
errMsg := fmt.Sprintf("Cannot deactivate %s service: %v", ServiceName, err)
errorMessages[ServiceName] = LogMessage{
level: log.LevelError,
message: fmt.Errorf("cannot deactivate %s service: %w",
ServiceName, err)}
fmt.Printf(uiSettings.iconError+" Cannot deactivate the %v service\n", ServiceName)
level: log.LevelError,
message: fmt.Errorf("%v", errMsg)}
disconnectResult.YggdrasilStopped = false
disconnectResult.YggdrasilStoppedError = errMsg
interactivePrintf("%v %v\n", uiSettings.iconError, errMsg)
} else {
fmt.Printf(uiSettings.iconOK+" Deactivated the %v service\n", ServiceName)
disconnectResult.YggdrasilStopped = true
interactivePrintf("%v Deactivated the %v service\n", uiSettings.iconOK, ServiceName)
}
durations[ServiceName] = time.Since(start)

/* 2. Disconnect from Red Hat Insights */
start = time.Now()
err = showProgress(" Disconnecting from Red Hat Insights...", unregisterInsights)
if err != nil {
errMsg := fmt.Sprintf("Cannot disconnect from Red Hat Insights: %v", err)
errorMessages["insights"] = LogMessage{
level: log.LevelError,
message: fmt.Errorf("cannot disconnect from Red Hat Insights: %w",
err)}
fmt.Printf(uiSettings.iconError + " Cannot disconnect from Red Hat Insights\n")
level: log.LevelError,
message: fmt.Errorf("%v", errMsg)}
disconnectResult.InsightsDisconnected = false
disconnectResult.InsightsDisconnectedError = errMsg
interactivePrintf("%v %v\n", uiSettings.iconError, errMsg)
} else {
fmt.Print(uiSettings.iconOK + " Disconnected from Red Hat Insights\n")
disconnectResult.InsightsDisconnected = true
interactivePrintf("%v Disconnected from Red Hat Insights\n", uiSettings.iconOK)
}
durations["insights"] = time.Since(start)

Expand All @@ -452,28 +552,31 @@ func disconnectAction(ctx *cli.Context) error {
" Disconnecting from Red Hat Subscription Management...", unregister,
)
if err != nil {
errMsg := fmt.Sprintf("Cannot disconnect from Red Hat Subscription Management: %v", err)
errorMessages["rhsm"] = LogMessage{
level: log.LevelError,
message: fmt.Errorf("cannot disconnect from Red Hat Subscription Management: %w",
err)}
fmt.Printf(
uiSettings.iconError + " Cannot disconnect from Red Hat Subscription Management\n",
)
level: log.LevelError,
message: fmt.Errorf("%v", errMsg)}

disconnectResult.RHSMDisconnected = false
disconnectResult.RHSMDisconnectedError = errMsg
interactivePrintf("%v %v\n", uiSettings.iconError, errMsg)
} else {
fmt.Printf(uiSettings.iconOK + " Disconnected from Red Hat Subscription Management\n")
disconnectResult.RHSMDisconnected = true
interactivePrintf("%v Disconnected from Red Hat Subscription Management\n", uiSettings.iconOK)
}
durations["rhsm"] = time.Since(start)

fmt.Printf("\nManage your connected systems: https://red.ht/connector\n")

showTimeDuration(durations)
if !uiSettings.isMachineReadable {
fmt.Printf("\nManage your connected systems: https://red.ht/connector\n")
showTimeDuration(durations)

err = showErrorMessages("disconnect", errorMessages)
if err != nil {
return err
err = showErrorMessages("disconnect", errorMessages)
if err != nil {
return err
}
}

return nil
return cli.Exit(disconnectResult, 0)
}

// canonicalFactAction tries to gather canonical facts about system,
Expand Down Expand Up @@ -519,24 +622,7 @@ func printJSONStatus(systemStatus *SystemStatus) error {

// beforeStatusAction ensures the user has supplied a correct `--format` flag.
func beforeStatusAction(ctx *cli.Context) error {
// This is run after the `app.Before()` has been run,
// the uiSettings is already set up for us to modify.
format := ctx.String("format")
switch format {
case "":
return nil
case "json":
uiSettings.isMachineReadable = true
uiSettings.isRich = false
return nil
default:
err := fmt.Errorf(
"unsupported format: %s (supported formats: %s)",
format,
`"json"`,
)
return cli.Exit(err, 1)
}
return setupFormatOption(ctx)
}

// statusAction tries to print status of system. It means that it gives
Expand Down Expand Up @@ -774,10 +860,18 @@ func main() {
Action: connectAction,
},
{
Name: "disconnect",
Name: "disconnect",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "format",
Usage: "prints output of disconnection in machine-readable format (supported formats: \"json\")",
Aliases: []string{"f"},
},
},
Usage: "Disconnects the system from " + Provider,
UsageText: fmt.Sprintf("%v disconnect", app.Name),
Description: fmt.Sprintf("The disconnect command disconnects the system from Red Hat Subscription Management, Red Hat Insights and %v and deactivates the %v service. %v will no longer be able to interact with the system.", Provider, ServiceName, Provider),
Before: beforeDisconnectAction,
subpop marked this conversation as resolved.
Show resolved Hide resolved
Action: disconnectAction,
},
{
Expand Down
4 changes: 2 additions & 2 deletions status.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ func rhsmStatus(systemStatus *SystemStatus) error {
if uiSettings.isMachineReadable {
systemStatus.RHSMConnected = false
} else {
fmt.Printf(uiSettings.iconInfo + " Not connected to Red Hat Subscription Management\n")
fmt.Printf("%v Not connected to Red Hat Subscription Management\n", uiSettings.iconInfo)
}
} else {
if uiSettings.isMachineReadable {
systemStatus.RHSMConnected = true
} else {
fmt.Printf(uiSettings.iconOK + " Connected to Red Hat Subscription Management\n")
fmt.Printf("%v Connected to Red Hat Subscription Management\n", uiSettings.iconOK)
}
}
return nil
Expand Down
Loading