-
Notifications
You must be signed in to change notification settings - Fork 20
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
Support other nextstrain.org-like remotes #333
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to mention that I made a few patches while looking into this for usage by CDC. Consider them as suggestions for this PR: 39fdb8a...ea3d185
Great, thanks! |
Brought all three into my local branch with:
and will probably fix them up into the primary commit. |
These come with the standard typing library as of Python 3.8.¹ ¹ <https://docs.python.org/3.8/whatsnew/3.8.html#typing>
Mypy 1.8.0 and some earlier versions complain about these two imports: $ mypy -p nextstrain.cli nextstrain/cli/runner/singularity.py:98: error: Name "docker" already defined (by an import) [no-redef] nextstrain/cli/runner/aws_batch/__init__.py:94: error: Name "docker" already defined (by an import) [no-redef] Found 2 errors in 2 files (checked 61 source files) …but there is no other definition of "docker" in those files! Mypy's got something wrong. These seem like new complaints as the code has existed for a while. Pyright does not complain. Adding reveal_type(docker) before the imports to see what each thinks produces: note: Revealed type is "types.ModuleType" from Mypy and information: Type of "docker" is "Unbound" from Pyright.
288be61
to
e74ee80
Compare
Adds support for other nextstrain.org-like remotes to the `nextstrain remote` family of commands, along with support for OIDC/OAuth2 authentication with them to the `nextstrain login` and related commands. Required IdP and client configuration for OIDC/OAuth2 is auto-discovered. One giant pile of changes, because I did not have time to go thru my typical editing and splitting process before going on leave. :/ Ah well. Related-to: <nextstrain/private#94>
It's handy and reassuring to be able to clear all login credentials without remembering what remotes you're logged into.
Steps to test this for current Nextstrain users: # Replace 'mac' with 'linux' or 'windows' if necessary
curl -fsSL --proto '=https' https://nextstrain.org/cli/installer/mac | bash -s pr-build/333
# Check you have the expected version
nextstrain version
# 7.4.0+git.aa9795f
nextstrain logout
nextstrain login
# Follow prompts |
@victorlin Those commands all ran as expected. I was able to |
@tsibley Confirmed that I wasn't testing the right thing because I installed the new CLI version and then ran a different older version that happened to have priority in my PATH. After confirming I was using the correct version, I got the web-based login and authentication worked as expected. I was surprised by the text output on the terminal, however, that said:
|
Tested web login in an Ubuntu docker container and it worked with manual copying of URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good by (brief) inspection. Minor comments. Tested via an otherwise empty docker image using the default nextstrain.org remote.
- Login flow via OIDC worked well, required manual pasting of URLs into the browser and then back to the CLI.
- Login flow using --username worked well.
`--username` or `-u`). See `nextstrain login --help` for more information. | ||
([#333](https://github.com/nextstrain/cli/pull/333)) | ||
|
||
* With the new support for being logged into multiple remotes, `nextstrain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the use case for being logged into multiple remotes simultaneously?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CDC will be running a Nextstrain Groups Server internally but also has Groups on nextstrain.org they use, so they'll be accessing two remotes: nextstrain.org and nextstrain.biotech.cdc.gov.
And other organizations have also expressed interest in having a Groups server they can use internally while still maintaining public Groups on nextstrain.org.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For development, it's also useful to be able to be manipulate authn with localhost:5000 without disrupting your normal nextstrain.org authn status.
|
||
nextstrain login | ||
nextstrain whoami | ||
nextstrain remote ls groups/test-private | ||
|
||
Most of the times the above is not necessary, however, as you can specify the | ||
local remote explicitly instead of pretending it's nextstrain.org, e.g.: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I interpret this section as saying the following are equivalent:
- Set default remote via env variable, e.g.
NEXTSTRAIN_DOT_ORG=http://localhost:5000 nextstrain login
andNEXTSTRAIN_DOT_ORG=http://localhost:5000 nextstrain remote ls groups/test
. - Specify remote in command, e.g.
nextstrain login localhost:5000
,nextstrain remote ls http://localhost:5000/groups/test
And that neither will access https://nextstrain.org. Is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have only a cursory understanding of how the CLI, nextstrain.org server (perhaps localhost) and cognito are interacting here.
When we login with nextstrain login localhost:5000
with the nextstrain.org server running at localhost:5000, is this remote the authz server as far as the CLI is concerned? And thus everything to do with cognito (user pools etc) has been lifted out of the CLI and into the remote? And thus any tokens the CLI receives are only ever interacting with the provided remote?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I interpret this section as saying the following are equivalent: […] And that neither will access https://nextstrain.org/. Is this correct?
They're equivalent except for the short code path before NEXTSTRAIN_DOT_ORG
is used to potentially override what "nextstrain.org" means (in nextstrain.cli.remote.parse_remote_path()
). That is, once the remote is parsed, they're equivalent.
Neither will access https://nextstrain.org itself.
When we login with
nextstrain login localhost:5000
with the nextstrain.org server running at localhost:5000, is this remote the authz server as far as the CLI is concerned? And thus everything to do with cognito (user pools etc) has been lifted out of the CLI and into the remote? And thus any tokens the CLI receives are only ever interacting with the provided remote?
No, the CLI still interacts with the OIDC/OAuth2 authorization server (aka the IdP), which in our case is Cognito but in CDC's case is Entra ID (née Azure AD). It obtains the IdP information from the remote, so it doesn't have to be hardcoded. I do have a rough WIP of docs for this interaction to help folks understand, but it's not up yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. At least this way the identity provider configuration has been lifted out of the CLI and into the remote.
print(f"Logged into nextstrain.org as {user.username}.") | ||
print("Log out with `nextstrain logout`.") | ||
print(f"Logged into {url.origin} as {user.username}.") | ||
print(f"Log out with `nextstrain logout {shquote(url.origin)}`.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would favor not printing the remote when it's the default (nextstrain.org).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't agree. I think because multiple remotes are possible, it's good to always be explicit to avoid confusing output.
Overall feedback seems positive and CDC is already running (successfully) the development builds from this PR, so I'll plan to merge and release today. I'd definitely welcome a deeper review of code and functionality and would be happy to discuss post-merge suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lots to digest in b4b29d0 but it was understandable. Looks good 👍
@victorlin pointed out¹ that a UserError is not raised by this function. While correcting that, I noted that other docstrings in this module use "saved credentials" as the term (matching the term we use in user-visible output) instead of "tokens", so I made this docstring follow suit. ¹ <#333 (comment)>
@victorlin suggested¹ we improve error handling in this code path, and he's right. Catch and improve the output for the three most common errors we'll encounter: connection errors, HTTP errors, and JSON decoding errors. The original error is summarized in the error output, and by chaining the new exception from the original, the full chain in all its detail will be printed when NEXTSTRAIN_DEBUG=1 for troubleshooting. ¹ <#333 (comment)>
Adds support for other nextstrain.org-like remotes to the
nextstrain remote
family of commands, along with support for OIDC/OAuth2 authentication with them to thenextstrain login
and related commands. Required IdP and client configuration for OIDC/OAuth2 is auto-discovered.One giant pile of changes, because I did not have time to go thru my typical editing and splitting process before going on leave. :/ Ah well.
Related-to: https://github.com/nextstrain/private/issues/94
Builds upon #332.
@victorlin I'm hopeful you can pick this up if needed before I'm back. I wish I'd had time to break it up into smaller changes.
At the least, without any additional work, this should provide CI builds of the standalone archives for testing, e.g. by installing them with:
To test this against our Azure AD/Entra ID testing directory, I created an app registration for the CLI (
68e51465-2672-4c47-92ab-bec0e919cf7a
). This required mapping AD/security groups to app roles, just like was done for the web server client. I then ran the nextstrain.org codebase with this bit of config.Note the redirect URI! This is the appropriate URI for production too, not just testing. A secret is also required, which is configured by env var.
Testing looks like then:
Checklist