Skip to content

Commit

Permalink
Merge pull request #49 from seqeralabs/add-custom-truststore-support
Browse files Browse the repository at this point in the history
Add custom java truststore support and improved exception handling
  • Loading branch information
drpatelh authored Jul 1, 2024
2 parents c3f4f83 + 847293a commit 9237376
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 17 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [[0.3.0](https://github.com/seqeralabs/nf-aggregate/releases/tag/0.3.0)] - 2024-07-01

### Credits

Special thanks to the following for their contributions to the release:

- [Adam Talbot](https://github.com/adamrtalbot)
- [Esha Joshi](https://github.com/ejseqera)
- [Rob Syme](https://github.com/robsyme)

Thank you to everyone else that has contributed by reporting bugs, enhancements or in any other way, shape or form.

### Enhancements & fixes

[PR #49](https://github.com/seqeralabs/nf-aggregate/pull/49) - Add custom java truststore support and improved exception handling

## [[0.2.0](https://github.com/seqeralabs/nf-aggregate/releases/tag/0.2.0)] - 2024-05-29

### Credits
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ nextflow run seqeralabs/nf-aggregate \
-profile docker
```
If you are using a Seqera Platform Enterprise instance that is secured with a private CA SSL certificate not recognized by default Java certificate authorities, you can specify a custom `cacerts` store path through the `--java_truststore_path` parameter and optionally, a password with the `--java_truststore_password`. This certificate will be used to achieve connectivity with your Seqera Platform instance through API and CLI.
## Output
The results from the pipeline will be published in the path specified by the `--outdir` and will consist of the following contents:
Expand Down
4 changes: 3 additions & 1 deletion main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ workflow {
ch_multiqc_logo,
params.seqera_api_endpoint,
params.skip_run_gantt,
params.skip_multiqc
params.skip_multiqc,
params.java_truststore_path,
params.java_truststore_password
)
}

Expand Down
2 changes: 2 additions & 0 deletions modules/local/plot_run_gantt/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ nextflow_process {
"""
input[0] = ['id': '4Bi5xBK6E2Nbhj', 'workspace': 'community/showcase']
input[1] = "https://api.tower.nf"
input[2] = ""
input[3] = ""
"""
}
}
Expand Down
30 changes: 26 additions & 4 deletions modules/local/seqera_runs_dump/functions.nf
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@

@Grab('com.github.groovy-wslite:groovy-wslite:1.1.2;transitive=false')
import wslite.rest.RESTClient
import groovy.json.JsonSlurper

// Set system properties for custom Java trustStore
def setTrustStore(trustStorePath, trustStorePassword) {
System.setProperty("javax.net.ssl.trustStore", trustStorePath)
if (trustStorePassword) {
System.setProperty("javax.net.ssl.trustStorePassword", trustStorePassword)
}
}

Long getWorkspaceId(orgName, workspaceName, client, authHeader) {
def orgResponse = client.get(path: '/orgs', headers: authHeader)
Expand All @@ -14,15 +22,22 @@ Long getWorkspaceId(orgName, workspaceName, client, authHeader) {
if (workspaceReponse.statusCode == 200) {
def workspaceMap = workspaceReponse.json?.workspaces.collectEntries { ws -> [ws.name, ws.id]}
return workspaceMap?.get(workspaceName)
} else {
log.error "Failed to fetch workspaces for orgId: ${orgId}, statusCode: ${workspaceResponse.statusCode}"
}
}
return null
}

Map getRunMetadata(meta, log, api_endpoint) {
Map getRunMetadata(meta, log, api_endpoint, trustStorePath, trustStorePassword) {
def runId = meta.id
def (orgName, workspaceName) = meta.workspace.tokenize("/")

if (trustStorePath) {
log.info "Setting custom truststore: ${trustStorePath}"
setTrustStore(trustStorePath, trustStorePassword)
}

def client = new RESTClient(api_endpoint)
def token = System.getenv("TOWER_ACCESS_TOKEN")
def authHeader = ["Authorization": "Bearer ${token}"]
Expand All @@ -39,11 +54,18 @@ Map getRunMetadata(meta, log, api_endpoint) {
return metaMap ?: [:]
}
}
} catch(Exception ex) {
} catch (wslite.rest.RESTClientException ex) {
log.warn """
Could not get workflow details for workflow ${runId} in workspace ${meta.workspace}:
↳ Status code ${ex.response.statusCode} returned from request to ${ex.request.url} (authentication headers excluded)
↳ Status code ${ex.response?.statusCode} returned from request to ${ex.request?.url} (authentication headers excluded)
""".stripIndent()
log.error "Exception: ${ex.message}", ex
} catch (Exception ex) {
log.warn """
An error occurred while getting workflow details for workflow ${runId} in workspace ${meta.workspace}:
${ex.message}
""".stripIndent()
log.error "Exception: ${ex.message}", ex
}
return [:]
}
8 changes: 7 additions & 1 deletion modules/local/seqera_runs_dump/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ process SEQERA_RUNS_DUMP {
input:
val meta
val api_endpoint
val java_truststore_path
val java_truststore_password

output:
tuple val(metaOut), path("${prefix}"), emit: run_dump
Expand All @@ -17,11 +19,15 @@ process SEQERA_RUNS_DUMP {
def args = task.ext.args ?: ''
def args2 = task.ext.args2 ?: ''
prefix = task.ext.prefix ?: "${meta.id}"
metaOut = meta + getRunMetadata(meta, log, api_endpoint)
metaOut = meta + getRunMetadata(meta, log, api_endpoint, java_truststore_path, java_truststore_password)
fusion = metaOut.fusion ? '--add-fusion-logs' : ''
javaTrustStore = java_truststore_path ? "-Djavax.net.ssl.trustStore=${java_truststore_path}" : ''
javaTrustStorePassword = java_truststore_password ? "-Djavax.net.ssl.trustStorePassword=${java_truststore_password}" : ''
"""
tw \\
$args \\
$javaTrustStore \\
$javaTrustStorePassword \\
--url=${api_endpoint} \\
--access-token=$TOWER_ACCESS_TOKEN \\
runs \\
Expand Down
1 change: 1 addition & 0 deletions modules/local/seqera_runs_dump/nextflow.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ process {
withName: 'SEQERA_RUNS_DUMP' {
ext.args = { params.seqera_cli_extra_args ? params.seqera_cli_extra_args.split("\\s(?=--)") : '' }
ext.args2 = { params.skip_run_gantt ? '' : '--add-task-logs' }
containerOptions = { params.java_truststore_path ? "--volume ${params.java_truststore_path}:${params.java_truststore_path}" : '' }
publishDir = [
path: { "${params.outdir}/${metaOut?.projectName?.replace("/", "_") ?: ""}/runs_dump" },
mode: params.publish_dir_mode,
Expand Down
2 changes: 2 additions & 0 deletions modules/local/seqera_runs_dump/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ nextflow_process {
"""
input[0] = ['id': '4Bi5xBK6E2Nbhj', 'workspace': 'community/showcase']
input[1] = "https://api.tower.nf"
input[2] = ""
input[3] = ""
"""
}
}
Expand Down
5 changes: 4 additions & 1 deletion nextflow.config
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ params {
// Seqera CLI options
seqera_api_endpoint = "https://api.cloud.seqera.io"
seqera_cli_extra_args = null
java_truststore_path = null
java_truststore_password = null

// MultiQC options
multiqc_config = null
multiqc_title = null
Expand Down Expand Up @@ -219,6 +222,6 @@ manifest {
mainScript = 'main.nf'
nextflowVersion = '!>=23.10.0'
defaultBranch = 'main'
version = '0.2.0'
version = '0.3.0'
doi = ''
}
10 changes: 10 additions & 0 deletions nextflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@
"description": "Extra arguments to pass to the Seqera Platform CLI command in addition to defaults defined by the pipeline.",
"fa_icon": "fas fa-plus"
},
"java_truststore_path": {
"type": "string",
"description": "Path to custom cacerts Java truststore used by Seqera Platform.",
"fa_icon": "fas fa-key"
},
"java_truststore_password": {
"type": "string",
"description": "Password for custom cacerts Java truststore used by Seqera Platform.",
"fa_icon": "fas fa-key"
},
"skip_run_gantt": {
"type": "boolean",
"description": "Skip GANTT chart creation for each run.",
Expand Down
24 changes: 14 additions & 10 deletions workflows/nf_aggregate/main.nf
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ include { paramsSummaryMap } from 'plugin/nf-validation'
workflow NF_AGGREGATE {

take:
ids // channel: run ids read in from --input
multiqc_custom_config // channel: user specified custom config file used by MultiQC
multiqc_logo // channel: logo rendered in MultiQC report
seqera_api_endpoint // val: Seqera Platform API endpoint URL
skip_run_gantt // val: Skip GANTT chart creation for each run
skip_multiqc // val: Skip MultiQC

ids // channel: run ids read in from --input
multiqc_custom_config // channel: user specified custom config file used by MultiQC
multiqc_logo // channel: logo rendered in MultiQC report
seqera_api_endpoint // val: Seqera Platform API endpoint URL
skip_run_gantt // val: Skip GANTT chart creation for each run
skip_multiqc // val: Skip MultiQC
java_truststore_path // val: Path to java truststore if using private certs
java_truststore_password // val: Password for java truststore if using private certs

main:

ch_versions = Channel.empty()
Expand All @@ -30,7 +32,9 @@ workflow NF_AGGREGATE {
//
SEQERA_RUNS_DUMP (
ids,
seqera_api_endpoint
seqera_api_endpoint,
java_truststore_path ?: '',
java_truststore_password ?: ''
)
ch_versions = ch_versions.mix(SEQERA_RUNS_DUMP.out.versions.first())

Expand All @@ -40,9 +44,9 @@ workflow NF_AGGREGATE {
SEQERA_RUNS_DUMP
.out
.run_dump
.filter {
.filter {
meta, run_dir ->
meta.fusion && !params.skip_run_gantt
meta.fusion && !params.skip_run_gantt
}
.set { ch_runs_for_gantt }

Expand Down
2 changes: 2 additions & 0 deletions workflows/nf_aggregate/tests/main.nf.test
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ nextflow_workflow {
input[3] = 'https://api.tower.nf'
input[4] = false
input[5] = false
input[6] = ""
input[7] = ""
"""
}
}
Expand Down

0 comments on commit 9237376

Please sign in to comment.