-
Notifications
You must be signed in to change notification settings - Fork 784
New command group: nextflow auth
#6380
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
Merged
Merged
Changes from 33 commits
Commits
Show all changes
69 commits
Select commit
Hold shift + click to select a range
0f9904e
WIP: First attempt at auth0 flow for 'nextflow auth login'
ewels b599fe1
Handle Enterprise installs without auth0
ewels 5fa52fc
Add auth0 client ID
ewels f031622
Hardcode 'platform' as audience as shouldn't ever need to edit this
ewels a0d800a
Add additional allowed API URLs for auth0 flow
ewels ec86e14
Use auth0 to generate a Platform PAT, add to bashrc
ewels 356e8f5
WIP: Started work on 'nextflow auth logout'
ewels b6b6127
Rewrite: Save to ~/.nextflow/config instead of using env vars
ewels ec03361
Always set tower.enabled true when logging in
ewels cf344f9
nextflow auth config
ewels f6f3694
Add code comment next to workspace ID saying what the org / ws is
ewels ba279b1
New nextflow auth status command
ewels 0b01234
Don't prompt for API URL, just have it as a CLI option
ewels 1909da0
Add warnings to login and logout if TOWER_ACCESS_TOKEN is set
ewels 0b3ffab
Bugfix: change how workspace name and fullName are used
ewels b31b1c7
Tell the user we're using their env var token in 'auth config'
ewels b9547ff
Add colour
ewels fa056b5
Refactor colour helpers to take string argument
ewels 320bee4
Minor tweak
ewels 39d3c64
Switch from PKCE to device-flow auth, with code confirmation
ewels 261e1e6
Add support for Platform auth on stage and prod
ewels 8a2b847
Tweak formatting
ewels a340b66
Auth flow with code, appended to URL
ewels 4c7cf83
Prompt to open browser, don't do it without warning
ewels 564890b
Rename AuthColorUtil to ColorUtil, expect to use it elsewhere
ewels 4015186
Improve styling and flow for status / auth
ewels 95908ff
lots of testing and tweaking CLI
ewels 3a67b90
Code cleanup
ewels 248fedc
Add some tests
ewels 5c7a192
move authcommand implementation to nf-tower
jorgee 4bdf462
Fix log
jorgee 0273b40
Fixing nf-tower load in AuthCommand
jorgee 00b4590
Spliting auth tests in nexflow and nf-tower
jorgee 1f56862
change modifications in .nextflow/config by /.nexflow/.login and incl…
jorgee 4f0773e
clean implementation and fix tests
jorgee b1d5301
include more tests
jorgee 29a2a54
Catch user cancellation of auth flow cleanly
ewels 4c2270f
Add confirmation when running 'auth logout'
ewels 21088fa
Rename .login to seqera_auth.config
ewels e148ed5
Tweaks to help text, status table printing
ewels f28cbc3
Improve CLI output when running config with workspaces
ewels b5852d7
Update tests
ewels 7f84c61
Check that the default workspace has CEs, and prompt to set one as pr…
ewels c53a4ee
auth status: show primary CE and default work directory
ewels 3f11aa8
Sort selection lists
ewels 2f35683
Update tests
ewels e42c958
Add nextflow auth docs
christopher-hakkaart 805843f
Update langauge for cli commands
christopher-hakkaart 864c209
Update language in install
christopher-hakkaart a0f633a
Revise text
christopher-hakkaart f17a8c2
Address comments
christopher-hakkaart 8df0ae8
Remove extra space
christopher-hakkaart 04c6b07
Merge pull request #3 from christopher-hakkaart/nextflow-auth
ewels e91848a
Merge branch 'master' into nextflow-auth
pditommaso 0ae13cf
Rename seqera_auth.config to seqera-auth.config
ewels 8f3e2eb
Move Auth0 keys into PlatformHelper library
ewels cf05f3f
Refactor getting token to use PlatformHelper.getAccessToken
ewels bb0ebe8
Remove unused AbortOperationException
ewels 7c0c8e4
Always log.debug when catching exceptions
ewels 217cb76
Fix regression with PlatformHelper.getAccessToken
ewels 342d33a
Update tests
ewels 84c3584
Tone down the colours a little
ewels 991579f
Use PlatformHelper for endpoint and workflow ID too
ewels 50b1671
Update test case
ewels 3730bea
Merge branch 'master' into nextflow-auth
ewels 1adf522
Show configured url in help text default
ewels 95caa00
Don't hardcode default endpoint
ewels 238e387
Update modules/nextflow/src/main/groovy/nextflow/platform/PlatformHel…
pditommaso b01e8fd
Add missing import
ewels File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
270 changes: 270 additions & 0 deletions
270
modules/nextflow/src/main/groovy/nextflow/cli/CmdAuth.groovy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,270 @@ | ||
| /* | ||
| * Copyright 2013-2025, Seqera Labs | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| package nextflow.cli | ||
|
|
||
| import com.beust.jcommander.Parameter | ||
| import com.beust.jcommander.Parameters | ||
| import groovy.transform.CompileStatic | ||
| import groovy.util.logging.Slf4j | ||
| import nextflow.Const | ||
| import nextflow.SysEnv | ||
| import nextflow.config.ConfigBuilder | ||
| import nextflow.exception.AbortOperationException | ||
| import nextflow.plugin.Plugins | ||
| import org.fusesource.jansi.Ansi | ||
| import org.pf4j.ExtensionPoint | ||
|
|
||
| import java.nio.file.Paths | ||
|
|
||
| import static org.fusesource.jansi.Ansi.* | ||
|
|
||
| import java.nio.file.Files | ||
| import java.nio.file.Path | ||
| import java.nio.file.StandardOpenOption | ||
| import java.util.concurrent.CompletableFuture | ||
| import java.util.concurrent.TimeUnit | ||
| import java.util.regex.Pattern | ||
|
|
||
| /** | ||
| * Implements the 'nextflow auth' commands | ||
| * | ||
| * @author Phil Ewels <phil.ewels@seqera.io> | ||
| */ | ||
| @Slf4j | ||
| @CompileStatic | ||
| @Parameters(commandDescription = "Manage Seqera Platform authentication") | ||
| class CmdAuth extends CmdBase implements UsageAware { | ||
|
|
||
| interface SubCmd { | ||
| String getName() | ||
| void apply(List<String> result) | ||
| void usage(List<String> result) | ||
| } | ||
|
|
||
| interface AuthCommand extends ExtensionPoint { | ||
| void login(String url) | ||
| void logout() | ||
| void config() | ||
| void status() | ||
| } | ||
|
|
||
| static public final String NAME = 'auth' | ||
|
|
||
| private List<SubCmd> commands = [] | ||
|
|
||
| private AuthCommand operation | ||
|
|
||
| String getName() { | ||
| return NAME | ||
| } | ||
|
|
||
| @Parameter(hidden = true) | ||
| List<String> args | ||
|
|
||
| @Parameter(names = ['-u', '-url'], description = 'Seqera Platform API endpoint') | ||
| String apiUrl | ||
|
|
||
| CmdAuth() { | ||
| commands.add(new LoginCmd()) | ||
| commands.add(new LogoutCmd()) | ||
| commands.add(new ConfigCmd()) | ||
| commands.add(new StatusCmd()) | ||
| } | ||
|
|
||
| void usage() { | ||
| usage(args) | ||
| } | ||
|
|
||
| void usage(List<String> args) { | ||
| List<String> result = [] | ||
| if (!args) { | ||
| result << this.getClass().getAnnotation(Parameters).commandDescription() | ||
| result << 'Usage: nextflow auth <sub-command> [options]' | ||
| result << '' | ||
| result << 'Commands:' | ||
| commands.collect { it.name }.sort().each { result << " $it".toString() } | ||
| result << '' | ||
| } else { | ||
| def sub = commands.find { it.name == args[0] } | ||
| if (sub) | ||
| sub.usage(result) | ||
| else { | ||
| throw new AbortOperationException("Unknown auth sub-command: ${args[0]}") | ||
| } | ||
| } | ||
| println result.join('\n').toString() | ||
| } | ||
|
|
||
| @Override | ||
| void run() { | ||
| if (!args) { | ||
| usage() | ||
| return | ||
| } | ||
| // load the Auth command implementation | ||
| this.operation = loadOperation() | ||
| if( !operation ) | ||
| throw new IllegalStateException("Unable to load auth extensions.") | ||
| // consume the first argument | ||
| getCmd(args).apply(args.drop(1)) | ||
| } | ||
|
|
||
| protected AuthCommand loadOperation(){ | ||
| // setup the plugins system and load the secrets provider | ||
| Plugins.init() | ||
| // load the config | ||
| Plugins.start('nf-tower') | ||
| // get Auth command operations implementation from plugins | ||
| return Plugins.getExtension(AuthCommand) | ||
| } | ||
|
|
||
| protected SubCmd getCmd(List<String> args) { | ||
| def cmd = commands.find { it.name == args[0] } | ||
| if (cmd) { | ||
| return cmd | ||
| } | ||
|
|
||
| def matches = commands.collect { it.name }.closest(args[0]) | ||
| def msg = "Unknown auth sub-command: ${args[0]}" | ||
| if (matches) | ||
| msg += " -- Did you mean one of these?\n" + matches.collect { " $it" }.join('\n') | ||
| throw new AbortOperationException(msg) | ||
| } | ||
|
|
||
| // | ||
| // nextflow auth login | ||
| // | ||
| class LoginCmd implements SubCmd { | ||
|
|
||
| @Override | ||
| String getName() { 'login' } | ||
|
|
||
| @Override | ||
| void apply(List<String> args) { | ||
| if (args.size() > 0) { | ||
| throw new AbortOperationException("Too many arguments for ${name} command") | ||
| } | ||
| operation.login(apiUrl) | ||
| } | ||
|
|
||
|
|
||
|
|
||
| @Override | ||
| void usage(List<String> result) { | ||
| result << 'Authenticate with Seqera Platform' | ||
| result << "Usage: nextflow auth $name [-u <endpoint>]".toString() | ||
| result << '' | ||
| result << 'Options:' | ||
| result << ' -u, -url <endpoint> Seqera Platform API endpoint (default: https://api.cloud.seqera.io)' | ||
| result << '' | ||
| result << 'This command will:' | ||
| result << ' 1. Display a URL and device code for OAuth2 authentication (Cloud) or prompt for PAT (Enterprise)' | ||
| result << ' 2. Wait for user to complete authentication in web browser' | ||
| result << ' 3. Generate and save access token to home-directory Nextflow config' | ||
| result << ' 4. Configure tower.accessToken, tower.endpoint, and tower.enabled settings' | ||
| result << '' | ||
| } | ||
| } | ||
|
|
||
| class LogoutCmd implements SubCmd { | ||
|
|
||
| @Override | ||
| String getName() { 'logout' } | ||
|
|
||
| @Override | ||
| void apply(List<String> args) { | ||
| if (args.size() > 0) { | ||
| throw new AbortOperationException("Too many arguments for ${name} command") | ||
| } | ||
| operation.logout() | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| void usage(List<String> result) { | ||
| result << 'Log out and remove Seqera Platform authentication' | ||
| result << "Usage: nextflow auth $name".toString() | ||
| result << '' | ||
| result << 'This command will:' | ||
| result << ' 1. Check if tower.accessToken is configured' | ||
| result << ' 2. Validate the token with Seqera Platform' | ||
| result << ' 3. Delete the PAT from Platform (only if Seqera Platform Cloud)' | ||
| result << ' 4. Remove the authentication from Nextflow config' | ||
| result << '' | ||
| } | ||
| } | ||
|
|
||
| // | ||
| // nextflow auth config | ||
| // | ||
| class ConfigCmd implements SubCmd { | ||
|
|
||
| @Override | ||
| String getName() { 'config' } | ||
|
|
||
| @Override | ||
| void apply(List<String> args) { | ||
| if (args.size() > 0) { | ||
| throw new AbortOperationException("Too many arguments for ${name} command") | ||
| } | ||
|
|
||
| operation.config() | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| void usage(List<String> result) { | ||
| result << 'Configure Seqera Platform settings' | ||
| result << "Usage: nextflow auth $name".toString() | ||
| result << '' | ||
| result << 'This command will:' | ||
| result << ' 1. Check authentication status' | ||
| result << ' 2. Configure tower.enabled setting for workflow monitoring' | ||
| result << ' 3. Configure default workspace (tower.workspaceId)' | ||
| result << '' | ||
| } | ||
| } | ||
|
|
||
| class StatusCmd implements SubCmd { | ||
|
|
||
| @Override | ||
| String getName() { 'status' } | ||
|
|
||
| @Override | ||
| void apply(List<String> args) { | ||
| if (args.size() > 0) { | ||
| throw new AbortOperationException("Too many arguments for ${name} command") | ||
| } | ||
| operation.status() | ||
| } | ||
|
|
||
|
|
||
| @Override | ||
| void usage(List<String> result) { | ||
| result << 'Show authentication status and configuration' | ||
| result << "Usage: nextflow auth $name".toString() | ||
| result << '' | ||
| result << 'This command shows:' | ||
| result << ' - Authentication status (yes/no) and source' | ||
| result << ' - API endpoint and source' | ||
| result << ' - Monitoring enabled status and source' | ||
| result << ' - Default workspace and source' | ||
| result << ' - System health status (API connection and authentication)' | ||
| result << '' | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.