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

fix: cli is not a library! #7891

Merged
merged 1 commit into from
Nov 6, 2023
Merged

fix: cli is not a library! #7891

merged 1 commit into from
Nov 6, 2023

Conversation

rb-determined-ai
Copy link
Member

Direct calls into the CLI are problematic, because the CLI uses a variety of authentication techniques, some of which are only configured by the cli's main() codepath. That means that cli auth and cert singletons have been configured all over e2e tests in order to support direct CLI calls.

Avoiding direct calls to cli functions is a step in the direction of cleaning up our authentication story.

@netlify
Copy link

netlify bot commented Sep 14, 2023

Deploy Preview for determined-ui ready!

Name Link
🔨 Latest commit bdb6efe
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/65494ea46305df00083c6e70
😎 Deploy Preview https://deploy-preview-7891--determined-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@rb-determined-ai rb-determined-ai force-pushed the rb/cli-not-a-library branch 3 times, most recently from 591eedc to 556d2e9 Compare September 18, 2023 18:17
Copy link
Member

@hamidzr hamidzr left a comment

Choose a reason for hiding this comment

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

looks good I don't have much to add here I'll let mlsys review unless there is a specific part you want me to look at

@@ -63,10 +62,10 @@ def test_trial_logs() -> None:
@pytest.mark.parametrize(
"task_type,task_config,log_regex",
[
(command.TaskTypeCommand, {"entrypoint": ["echo", "hello"]}, re.compile("^.*hello.*$")),
Copy link
Member

Choose a reason for hiding this comment

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

hmm why?

Copy link
Member Author

Choose a reason for hiding this comment

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

because the CLI is not a library. It should never be imported from outside the cli/ directory.

Importing it for a few static strings is a violation of the application-nature of the CLI, with no particular benefit. I don't think these strings are going to change in the next 10 years.

Copy link
Member

Choose a reason for hiding this comment

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

I didn't check where the command namespace was coming from. makes sense.

@rb-determined-ai rb-determined-ai force-pushed the rb/cli-not-a-library branch 2 times, most recently from 92b36be to fc341b8 Compare September 19, 2023 15:23
Copy link
Contributor

@wes-turner wes-turner left a comment

Choose a reason for hiding this comment

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

Reviewing the relocation of functionality from the CLI to determined.common.api. Not reviewing its contents, which I think are out of scope for this PR.

LGTM. Thanks for making this better.

harness/determined/common/api/_util.py Outdated Show resolved Hide resolved
user = bindings.v1User(username=api_utils.get_random_string(), admin=False, active=True)
creds = api_utils.create_test_user(True, user=user)
for role in roles:
api.assign_role(
Copy link
Contributor

Choose a reason for hiding this comment

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

Excision of determined.cli.rbac.assign_role into determined.common.api.assign_role looks great, as does its use here. api.assign_role seems like a pretty reasonable place to call something from that fronts the backend. But there's something about it living in determined.common.api._util that feels wrong to me. It's a nit either way, and who really cares what file the function is in, but if you think that it'll be helpful to us to someday have structure to that directory, I think now is a good time to start it.

Copy link
Member Author

Choose a reason for hiding this comment

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

I really don't care what file the function is in. If you want me to put it in a different file, lmk what to name it and I'll do it.

I do like having it in the api namespace, and this is a case where I really like the separation between how code is called and where code is defined.

Copy link
Contributor

Choose a reason for hiding this comment

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

I do like having it in the api namespace, and this is a case where I really like the separation between how code is called and where code is defined.

I've not had cause to differentiate the two in the past, but I agree. It's really nice, here.

This comment applies to many of the other moved functions, too. How about determined/common/api/_rbac.py?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think that sounds like a great name.

I put all the functions I added there, since they're all rbac-related. Even not_found_errs is rbac-related.

Copy link
Contributor

Choose a reason for hiding this comment

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

👍 I like it.

return bindings.get_GetWorkspace(session, id=w[0].id).workspace


# not_found_errs mirrors NotFoundErrs from the golang api/errors.go. In the cases where
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't get what's going on with this function. Could it be part of your cleanup?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I'll look into it. I didn't ask that question earlier, I just shuffled it around.

Copy link
Member Author

Choose a reason for hiding this comment

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

looked into it. It just helps users remember that 404 errors in rbac cases might be permissions errors.

I promoted the comment to a docstring and added more explanation.

Copy link
Contributor

@wes-turner wes-turner Sep 28, 2023

Choose a reason for hiding this comment

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

The docstring is a better place to put the help text, for sure. And thanks for figuring out what the function is for.

I still have to do more work to understand what the function does than I want a person to have to do. Something seems off about the design. Bleh.

But anyway, I think bigger changes are outside the scope of this PR. So maybe here just a suggestion like:

"""Construct a NotFoundException from passed strings.

This function creates NotFoundExceptions with the same syntax as the NotFoundErrs from api/errors.go so that messages from both layers look the same. If RBAC is enabled, the exceptions underlying the 404s that this function constructs might be the result of a permissions error. In that event, this function appends a suggestion to the constructed exception string that the user to check permissions.
"""

The type mismatch between the actual return type and its superclass is a little weird. That'd be an easy fix if you want to make it.

group_name_to_assign: Optional[str] = None,
) -> Tuple[List[bindings.v1UserRoleAssignment], List[bindings.v1GroupRoleAssignment]]:
if (username_to_assign is None) == (group_name_to_assign is None):
# XXX: very weird that we use api.errors.BadRequestException here!
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't forget to either remove me or turn this into a TODO and/or ticket.

Copy link
Member Author

Choose a reason for hiding this comment

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

ah yes, thank you

@rb-determined-ai rb-determined-ai force-pushed the rb/cli-not-a-library branch 2 times, most recently from b38bfa3 to 5d3a5ba Compare September 29, 2023 19:32
Copy link
Contributor

@stoksc stoksc left a comment

Choose a reason for hiding this comment

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

backend lgtm as long as tests pass

@rb-determined-ai
Copy link
Member Author

status update: this is blocked on bringing the EE changes in e2e_tests into the OSS repo.

We can't solve the rebase problem for the whole world, but we can solve it for this directory!

@rb-determined-ai
Copy link
Member Author

status update: EE changes to e2e_tests are finally in OSS now, and this PR can proceed as planned.

raise api.errors.BadRequestException(f"could not find role name {role_name}")


def create_assignment_request(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't like this method. It's got all kinds of weird. It's not your job, but do you want to be the person on the other side of the git blame?

I think it should be split into:

create_user_assignment_request(session, role, workspace, username) -> bindings.v1UserRoleAssignment
create_group_assignment_request(session, role, workspace, group) -> bindings.v1GroupRoleAssignment

Copy link
Member Author

Choose a reason for hiding this comment

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

lol, you are exactly right. I didn't even read the function body.

@rb-determined-ai rb-determined-ai changed the title fix: cli is not a library! fix: cli is not a library! Nov 3, 2023
@rb-determined-ai rb-determined-ai changed the title fix: cli is not a library! fix: cli is not a library! Nov 3, 2023
Copy link
Contributor

@wes-turner wes-turner left a comment

Choose a reason for hiding this comment

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

New changes yes.

Direct calls into the CLI are problematic, because the CLI uses a
variety of authentication techniques, some of which are only configured
by the cli's __main__() codepath.  That means that cli auth and cert
singletons have been configured all over e2e tests in order to support
direct CLI calls.

Avoiding direct calls to cli functions is a step in the direction of
cleaning up our authentication story.
@rb-determined-ai
Copy link
Member Author

I removed a review request from the web team, seems to have been from an old force-push-to-master incident.

@rb-determined-ai
Copy link
Member Author

Everything passed except some known flakes. Same story over in the EE repo. Force-merging.

@rb-determined-ai rb-determined-ai merged commit af995ba into main Nov 6, 2023
68 of 80 checks passed
@rb-determined-ai rb-determined-ai deleted the rb/cli-not-a-library branch November 6, 2023 21:23
@dannysauer dannysauer added this to the 0.26.4 milestone Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants