Skip to content

Commit

Permalink
feat: register with content templates
Browse files Browse the repository at this point in the history
    * register to templates with --content-template
    * https://issues.redhat.com/browse/CCT-769
  • Loading branch information
rverdile committed Nov 13, 2024
1 parent e76ed8f commit 4ebc91b
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ BUILDROOT
RPMS
SOURCES
SRPMS
.idea
6 changes: 6 additions & 0 deletions connect_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func beforeConnectAction(ctx *cli.Context) error {
password := ctx.String("password")
organization := ctx.String("organization")
activationKeys := ctx.StringSlice("activation-key")
contentTemplates := ctx.StringSlice("content-template")

if len(activationKeys) > 0 {
if username != "" {
Expand All @@ -66,6 +67,11 @@ func beforeConnectAction(ctx *cli.Context) error {
}
}

if len(contentTemplates) > 0 && organization == "" {
err := fmt.Errorf("--organization is required, when --content-template is used")
return cli.Exit(err, 1)
}

// When machine-readable format is used, then additional requirements have to be met
if uiSettings.isMachineReadable {
if username == "" || password == "" {
Expand Down
5 changes: 5 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ func main() {
Usage: "register with `KEY`",
Aliases: []string{"a"},
},
&cli.StringSliceFlag{
Name: "content-template",
Usage: "register with `CONTENT_TEMPLATE",
Aliases: []string{"c"},
},
&cli.StringFlag{
Name: "server",
Hidden: true,
Expand Down
101 changes: 96 additions & 5 deletions rhsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func unpackOrgs(s string) ([]string, error) {
// registerUsernamePassword tries to register system against candlepin server (Red Hat Management Service)
// username and password are mandatory. When organization is not obtained, then this method
// returns list of available organization and user can select one organization from the list.
func registerUsernamePassword(username, password, organization, serverURL string) ([]string, error) {
func registerUsernamePassword(username, password, organization string, environments []string, serverURL string) ([]string, error) {
var orgs []string
if serverURL != "" {
if err := configureRHSM(serverURL); err != nil {
Expand Down Expand Up @@ -132,6 +132,23 @@ func registerUsernamePassword(username, password, organization, serverURL string
return orgs, err
}

var options = make(map[string]string)
options["enable_content"] = "true"

if len(environments) > 0 && organization != "" {
envList, err := getEnvironmentsList(privConn, username, password, organization)
if err != nil {
return orgs, err
}

envIDs, err := mapEnvironmentNamesToIDs(environments, envList, true)
if err != nil {
return orgs, err
}

options["environments"] = strings.Join(envIDs, ",")
}

if err := privConn.Object(
"com.redhat.RHSM1",
"/com/redhat/RHSM1/Register").Call(
Expand All @@ -140,7 +157,7 @@ func registerUsernamePassword(username, password, organization, serverURL string
organization,
username,
password,
map[string]string{"enable_content": "true"},
options,
map[string]string{},
locale).Err; err != nil {

Expand Down Expand Up @@ -407,6 +424,7 @@ func registerRHSM(ctx *cli.Context) (string, error) {
password := ctx.String("password")
organization := ctx.String("organization")
activationKeys := ctx.StringSlice("activation-key")
contentTemplates := ctx.StringSlice("content-template")

if len(activationKeys) == 0 {
if username == "" {
Expand Down Expand Up @@ -444,9 +462,9 @@ func registerRHSM(ctx *cli.Context) (string, error) {
} else {
var orgs []string
if organization != "" {
_, err = registerUsernamePassword(username, password, organization, ctx.String("server"))
_, err = registerUsernamePassword(username, password, organization, contentTemplates, ctx.String("server"))
} else {
orgs, err = registerUsernamePassword(username, password, "", ctx.String("server"))
orgs, err = registerUsernamePassword(username, password, "", contentTemplates, ctx.String("server"))
/* 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. */
Expand Down Expand Up @@ -481,7 +499,7 @@ func registerRHSM(ctx *cli.Context) (string, error) {
}

// Try to register once again with given organization
_, err = registerUsernamePassword(username, password, organization, ctx.String("server"))
_, err = registerUsernamePassword(username, password, organization, contentTemplates, ctx.String("server"))
}
}
}
Expand All @@ -494,3 +512,76 @@ func registerRHSM(ctx *cli.Context) (string, error) {
}
return successMsg, nil
}

type Environment struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Type string `json:"type"`
}

func (e *Environment) isContentTemplate() bool {
return e.Type == "content-template"
}

func unpackEnvironments(s string) ([]Environment, error) {
var environments []Environment
err := json.Unmarshal([]byte(s), &environments)
if err != nil {
return nil, err
}
return environments, nil
}

func getEnvironmentsList(conn *dbus.Conn, username, password, organization string) ([]Environment, error) {
var err error
locale := getLocale()
obj := conn.Object("com.redhat.RHSM1.Register", "/com/redhat/RHSM1/Register")
var envString string
if err := obj.Call(
"com.redhat.RHSM1.Register.GetEnvironments",
dbus.Flags(0),
username,
password,
organization,
map[string]string{},
locale).Store(&envString); err != nil {
return nil, unpackRHSMError(err)
}

var environments []Environment
if environments, err = unpackEnvironments(envString); err != nil {
return nil, err
}

return environments, nil
}

func mapEnvironmentNamesToIDs(names []string, environmentList []Environment, contentTemplates bool) ([]string, error) {
var ids []string

for _, name := range names {
found := false
for _, environment := range environmentList {
if environment.Name == name {
ids = append(ids, environment.ID)
found = true
}
if found {
if contentTemplates && !environment.isContentTemplate() {
return nil, fmt.Errorf("environment \"%s\" is not a content template", environment.Name)
}
break
}
}
if !found {
typeString := "environment"
if contentTemplates {
typeString = "content template"
}
return nil, fmt.Errorf(typeString+" named \"%s\" was not found", name)
}
}

return ids, nil
}

0 comments on commit 4ebc91b

Please sign in to comment.