Skip to content
Draft
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
15 changes: 8 additions & 7 deletions cmd/rhc/connect_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ import (
"strings"
"time"

"github.com/redhatinsights/rhc/internal/features"
"github.com/redhatinsights/rhc/internal/rhsm"
"github.com/urfave/cli/v2"

"github.com/redhatinsights/rhc/internal/datacollection"
"github.com/redhatinsights/rhc/internal/features"
"github.com/redhatinsights/rhc/internal/remotemanagement"
"github.com/redhatinsights/rhc/internal/rhsm"
"github.com/redhatinsights/rhc/internal/ui"
"github.com/urfave/cli/v2"
)

type FeatureResult struct {
Expand Down Expand Up @@ -77,7 +76,8 @@ func (connectResult *ConnectResult) errorMessages() map[string]string {
// will be stored in RHSMConnectError.
func (connectResult *ConnectResult) TryRegisterRHSM(ctx *cli.Context) {
slog.Info("Registering the system with Red Hat Subscription Management")
returnedMsg, err := rhsm.RegisterRHSM(ctx, features.ContentFeature.Enabled)

err := registerRHSM(ctx)
if err != nil {
connectResult.RHSMConnected = false
connectResult.RHSMConnectError = fmt.Sprintf("cannot connect to Red Hat Subscription Management: %s", err)
Expand All @@ -96,8 +96,8 @@ func (connectResult *ConnectResult) TryRegisterRHSM(ctx *cli.Context) {
)
} else {
connectResult.RHSMConnected = true
slog.Debug(returnedMsg)
ui.Printf("%s[%v] %s\n", ui.Indent.Small, ui.Icons.Ok, returnedMsg)
slog.Debug("Connected to Red Hat Subscription Management")
ui.Printf("%s[%v] Connected to Red Hat Subscription Management\n", ui.Indent.Small, ui.Icons.Ok)
if features.ContentFeature.Enabled {
connectResult.Features.Content.Successful = true
slog.Info("redhat.repo has been generated")
Expand Down Expand Up @@ -218,6 +218,7 @@ func beforeConnectAction(ctx *cli.Context) error {

// When machine is already connected, then return error
slog.Info("Checking system connection status")

uuid, err := rhsm.GetConsumerUUID()
if err != nil {
return cli.Exit(
Expand Down
3 changes: 2 additions & 1 deletion cmd/rhc/disconnect_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@ func (disconnectResult *DisconnectResult) TryUnregisterInsightsClient() error {
func (disconnectResult *DisconnectResult) TryUnregisterRHSM() error {
slog.Info("Unregistering system from Red Hat Subscription Management")

isRegistered, err := rhsm.IsRHSMRegistered()
isRegistered, err := rhsm.IsSystemRegistered()
if err != nil {
return err
}

if !isRegistered {
infoMsg := "Already disconnected from Red Hat Subscription Management"
disconnectResult.RHSMDisconnected = true
Expand Down
122 changes: 122 additions & 0 deletions cmd/rhc/rhsm.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
package main

import (
"bufio"
"fmt"
"log/slog"
"os"
"strings"
"text/tabwriter"
"time"

"github.com/briandowns/spinner"
"github.com/redhatinsights/rhc/internal/features"
"github.com/redhatinsights/rhc/internal/rhsm"
"github.com/redhatinsights/rhc/internal/ui"
"github.com/urfave/cli/v2"
"golang.org/x/term"
)

// readOrganization displays the available organizations in a tabular format
// and prompts the user to select one. It returns the organization name entered
// by the user.
func readOrganization(availableOrgs []string) string {
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Available Organizations:")
writer := tabwriter.NewWriter(os.Stdout, 0, 2, 2, ' ', 0)
for i, org := range availableOrgs {
_, _ = fmt.Fprintf(writer, "%v\t", org)
if (i+1)%4 == 0 {
_, _ = fmt.Fprint(writer, "\n")
}
}
_ = writer.Flush()
fmt.Print("\nOrganization: ")
_ = scanner.Scan()
organization := strings.TrimSpace(scanner.Text())
fmt.Printf("\n")
return organization
}

// registerRHSM controls the actual registration flow for connecting the system
// to Red Hat Subscription Management. It handles both username/password and
// activation key registration methods. If credentials are not provided via flags,
// it prompts the user interactively. When the user belongs to multiple organizations
// and no organization is specified, it prompts the user to select one from the
// available list.
func registerRHSM(ctx *cli.Context) error {
username := ctx.String("username")
password := ctx.String("password")
organization := ctx.String("organization")
activationKeys := ctx.StringSlice("activation-key")
contentTemplates := ctx.StringSlice("content-template")
enableContent := features.ContentFeature.Enabled

if len(activationKeys) == 0 {
if username == "" {
password = ""
scanner := bufio.NewScanner(os.Stdin)
fmt.Print("Username: ")
_ = scanner.Scan()
username = strings.TrimSpace(scanner.Text())
}
if password == "" {
fmt.Print("Password: ")
data, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil {
return fmt.Errorf("unable to read password: %w", err)
}
password = string(data)
fmt.Printf("\n\n")
}
}

var s *spinner.Spinner
if ui.IsOutputRich() {
s = spinner.New(spinner.CharSets[9], 100*time.Millisecond)
s.Prefix = ui.Indent.Small + "["
s.Suffix = "] Connecting to Red Hat Subscription Management..."
s.Start()
defer s.Stop()
}

registerServer, err := rhsm.NewRegisterServer()
if err != nil {
return err
}

defer func() {
if err = registerServer.Close(); err != nil {
slog.Debug(err.Error())
}
}()

if len(activationKeys) > 0 {
return registerServer.RegisterWithActivationKeys(
organization,
activationKeys,
contentTemplates,
enableContent,
)
}

err = registerServer.RegisterWithUsernamePassword(username, password, organization, contentTemplates, enableContent)
if rhsm.IsOrgNotSpecified(err) {
/* When organization was not specified using CLI option --organization, and it is
required, because user is member of more than one organization, then ask for
the organization. */
var orgs []string
orgs, err = registerServer.GetOrganizations(username, password)
if err != nil {
return err
}

// Ask for organization and display hint with list of organizations
organization = readOrganization(orgs)

// Try to register once again with given organization
return registerServer.RegisterWithUsernamePassword(username, password, organization, contentTemplates, enableContent)
}

return err
}
27 changes: 6 additions & 21 deletions cmd/rhc/status_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@ import (
"reflect"
"time"

"github.com/godbus/dbus/v5"
"github.com/redhatinsights/rhc/internal/rhsm"
"github.com/urfave/cli/v2"

"github.com/briandowns/spinner"
systemd "github.com/coreos/go-systemd/v22/dbus"

"github.com/redhatinsights/rhc/internal/datacollection"
"github.com/redhatinsights/rhc/internal/localization"
"github.com/redhatinsights/rhc/internal/ui"
)

Expand Down Expand Up @@ -54,41 +52,28 @@ func rhsmStatus(systemStatus *SystemStatus) error {
func isContentEnabled(systemStatus *SystemStatus) error {
slog.Info("Checking content status")

conn, err := dbus.SystemBus()
contentEnabled, err := rhsm.IsContentEnabled()
if err != nil {
return fmt.Errorf("cannot connect to system D-Bus: %w", err)
}

locale := localization.GetLocale()

config := conn.Object("com.redhat.RHSM1", "/com/redhat/RHSM1/Config")

var contentEnabled string
if err := config.Call(
"com.redhat.RHSM1.Config.Get",
0,
"rhsm.manage_repos",
locale).Store(&contentEnabled); err != nil {
systemStatus.returnCode += 1
systemStatus.ContentError = err.Error()
return rhsm.UnpackDBusError(err)
return err
}

uuid, err := rhsm.GetConsumerUUID()
isRegistered, err := rhsm.IsSystemRegistered()
if err != nil {
systemStatus.returnCode += 1
systemStatus.ContentError = err.Error()
return fmt.Errorf("unable to get consumer UUID: %s", err)
return err
}

if contentEnabled == "1" && uuid != "" {
if contentEnabled && isRegistered {
systemStatus.ContentEnabled = true
infoMsg := "Red Hat repository file generated"
slog.Info(infoMsg)
ui.Printf("%s[%v] Content ... %v\n", ui.Indent.Medium, ui.Icons.Ok, infoMsg)
} else {
systemStatus.ContentEnabled = false
if uuid != "" {
if isRegistered {
infoMsg := "Generating of Red Hat repository file disabled in rhsm.conf"
slog.Info(infoMsg)
ui.Printf("%s[ ] Content ... %v\n", ui.Indent.Medium, infoMsg)
Expand Down
Loading
Loading