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: register with content templates #168

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rverdile
Copy link

@rverdile rverdile commented Nov 13, 2024

Card ID: CCT-769.

This is dependent on this PR, which the requirements are still being discussed, so I'm leaving this in draft for now.

This PR implements a new option to register with a content template, given the content template name. Since content templates are implemented as environments in candlepin, I've tried to implement this such that some code could be re-used in the future for registering with environments.

Feedback is appreciated and welcome :)

Still needs

  • To handle activation keys
  • To handle when GetEnvironments() is not available

@Archana-PandeyM
Copy link

/packit build

@rverdile rverdile marked this pull request as ready for review December 2, 2024 13:49
Copy link
Contributor

@jirihnidek jirihnidek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your PR. Overall, it works. 👍

I have to apologize. We agreed that we will support only environment with type == content-template. Thus, it will be possible to simplify your PR on some places. You can find more details in my comments.

I have some other requests.

rhsm.go Outdated
if len(environments) > 0 && organization != "" {
var useEnvIDs = false
envList, err := getEnvironmentsList(privConn, username, password, organization)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If err is not nil, then orgs with error should be returned. We will not allow to use content-templates on the systems, where D-Bus method GetEnvironments() is not available.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this is a nice simplification. And now I'm thinking alternating to using the ID would not be useful in the case of content templates. @ptoscano wrote the ticket so he may want to provide some input here.

rhsm.go Outdated
return environments, nil
}

func mapEnvironmentIDsToNames(names []string, environmentList []Environment, contentTemplates bool) ([]string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few notes:

  • The name of this function is not correct. You try to get environment IDs from environment names. Thus the name should be something like mapEnvironmentNamesToIds() or getContentTemplateIds(). You return list (not map) of environments with type == "content-template". I vote for getContentTemplateIds().
  • This method is missing doc string with description.
  • Variable contentTemplates bool could be removed.
  • You can also name returned variables. Something like:
func getContentTemplateIds()(names []string, environmentList []Environment, contentTemplates bool) (envIDs []string, err error) {
// Body of function

rhsm.go Outdated
Comment on lines 589 to 592
typeString := "environment"
if contentTemplates {
typeString = "content template"
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be removed, because we will support only environments with type == "content-template"

rhsm.go Outdated
if contentTemplates {
typeString = "content template"
}
return nil, fmt.Errorf(typeString+" named \"%s\" was not found", name)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error should be modified and the logic of error detection should be also modified.

I claim that we should return error if any of provided environment is not found or the type is not "content-type".

rhsm.go Outdated
return environments, nil
}

func getEnvironmentsList(conn *dbus.Conn, username, password, organization string) ([]Environment, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc string is missing of this function.

rhsm.go Outdated
return e.Type == "content-template"
}

func unpackEnvironments(s string) ([]Environment, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc string is missing.

if err := privConn.Object(
"com.redhat.RHSM1",
"/com/redhat/RHSM1/Register").Call(
"com.redhat.RHSM1.Register.RegisterWithActivationKeys",
dbus.Flags(0),
orgID,
activationKeys,
map[string]string{},
options,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The registration using activation key & org & content templates does not work.

You cannot do it so simple, when activation key(s) are used for registration. You cannot use environment names as environment IDs. You have to get IDs from environment names in the same way as you do it for registration using username & password.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GetEnvironments() method requires username and password, so the intention here was to assume that the given values are the IDs.

But now I am wondering if using activation keys with templates should be prevented? The ID is not really usable in the case of content templates. @ptoscano wrote the ticket he want to provide some input.

Copy link
Contributor

@jirihnidek jirihnidek Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you are right. Getting environments requires username and password...

Hmm, It would be easy to simply say that content templates are supported only with username and password authentication, but user experience would not be the best.

Other approach: requiring environment name for username & password and requiring environment ID (typically some UUID) for activation key authentication would be very very confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem here is due to the difference in behaviour of two types of "credentials": username & password, activation key(s) (AKs) + org id:

  • username & password are real credentials: they are used when authenticating to Candlepin (via HTTP Basic Auth), and thus the identity of the caller is immediately known even before the code of the actual endpoint is run
  • AKs are "credentials", yes, however they are actually metadata passed when calling the POST /consumers endpoint. They currently cannot be used for anything else than that

Environments have been historically handled in a "special way": so far they are Katello-only feature, and for reasons I'm not even sure about they were implemented in Katello directly (since Katello proxies the communication to its Candlepin instance) as part of AKs. When connecting directly to Candlepin there is (or better, used to be) no possibility to specify environments with AKs. Hence, if the IDs and names of AKs are different, they don't generally matter in a Katello setup.

Strictly speaking, the org ID has the same inconsistency as environments:

  • sub-man does resolve the org name from the available ones when registering with username & password, or even what is passed via --org
  • sub-man uses --org as-is when registering with AKs

The above inconsistency for org ID practically has not been an issue because:

  • when registering to Hosted, the org ID and names are the same (numeric strings)
  • when registering to Katello, the automated registration ways such as the global registration take care of pre-filling the script to run (and the script uses AKs)
  • registration to Katello via username & password is not commonly done

Because of the above, IMHO there is not much that can be done to avoid the inconsistencies from Candlepin; my recommendation is to:

  • resolve content templates names -> IDs when registering via username & password, as that is usually done manually (and thus the user better expect user-facing bits)
  • assume that the specified content templates are IDs when registering via AKs

Copy link
Contributor

@jirihnidek jirihnidek Dec 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the above, IMHO there is not much that can be done to avoid the inconsistencies from Candlepin; my recommendation is to:

  • resolve content templates names -> IDs when registering via username & password, as that is usually done
    manually (and thus the user better expect user-facing bits)
  • assume that the specified content templates are IDs when registering via AKs

No, I will never accept anything like this! Because it would very confusing user experience. If this proposal was implemented, then we would see many customer cases related to this inconsistency (environment names for username & password, environment IDs for activation-keys & orgs).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been thinking about this problem and I think that cleanest solution is to use environment IDs in both cases (authentication using username & password, authentication using activation-key & org). Could environment IDs be some e.g. UUID. Yes, it could happen. Do users care? Not really, because if environment names were supported, then they would probably copy paste environment names to command line anyway. So, it does not matter, what they copy paste.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A candlepin dev pointed out that candlepin can natively accept the environment name:

Candlepin supports using either environment names or ids during registration. Just pass it like this in the consumer payload:
{
  "environments": [
     {
       "name": "my_environment_name"
       }
    ]
 }

Any reason to not go that route?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is probably doable, but something like this would be necessary for subscription-manager first: candlepin/subscription-manager#3480

@jirihnidek
Copy link
Contributor

Following change in rhsm.service candlepin/subscription-manager#3480 would allow to simplify implementation of content template.

  1. It will be possible to use environment names directly for both authentication methods
  2. It will be possible to specify environment_type in argument of Register() and RegisterWithActivationKeys()
  3. Thus, there will be no need to call GetEnvironments() D-Bus method and registration will not be blocked by another REST API call.

    * card ID: CCT-769
    * register to templates with --content-template <name>
@rverdile
Copy link
Author

Made the changes based on the new subscription manager PR!

@jirihnidek
Copy link
Contributor

@rverdile I just merged candlepin/subscription-manager#3480 to main ... I will review your PR tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants