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

sentieon-bwamem #994

Merged
merged 12 commits into from
Apr 13, 2023
19 changes: 18 additions & 1 deletion .github/workflows/pytest-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ jobs:
tags: vep
- profile: "conda"
tags: concatenate_vcfs
- profile: "conda"
tags: sentieon/bwaindex
asp8200 marked this conversation as resolved.
Show resolved Hide resolved
- profile: "conda"
tags: sentieon/bwamem
- profile: "singularity"
tags: merge
- profile: "singularity"
Expand All @@ -62,6 +66,7 @@ jobs:
env:
NXF_ANSI_LOG: false
TEST_DATA_BASE: "${{ github.workspace }}/test-datasets"
SENTIEON_LICENSE_BASE64: ${{ secrets.SENTIEON_LICENSE_BASE64 }}
steps:
- name: Check out pipeline code
uses: actions/checkout@v3
Expand Down Expand Up @@ -108,7 +113,7 @@ jobs:
${{ runner.os }}-pip-

- name: Install Python dependencies
run: python -m pip install --upgrade pip pytest-workflow
run: python -m pip install --upgrade pip pytest-workflow cryptography

- uses: actions/cache@v3
with:
Expand Down Expand Up @@ -136,6 +141,18 @@ jobs:
channels: conda-forge,bioconda,defaults
python-version: ${{ matrix.python-version }}

# Set up secrets
- name: Set up nextflow secrets
if: env.SENTIEON_LICENSE_BASE64 != null
run: |
nextflow secrets set SENTIEON_LICENSE_BASE64 ${{ secrets.SENTIEON_LICENSE_BASE64 }}
nextflow secrets set SENTIEON_AUTH_MECH_BASE64 ${{ secrets.SENTIEON_AUTH_MECH_BASE64 }}
SENTIEON_ENCRYPTION_KEY=$(echo -n "${{ secrets.ENCRYPTION_KEY_BASE64 }}" | base64 -d)
SENTIEON_LICENSE_MESSAGE=$(echo -n "${{ secrets.LICENSE_MESSAGE_BASE64 }}" | base64 -d)
SENTIEON_AUTH_DATA=$(python bin/license_message.py encrypt --key "$SENTIEON_ENCRYPTION_KEY" --message "$SENTIEON_LICENSE_MESSAGE")
SENTIEON_AUTH_DATA_BASE64=$(echo -n "$SENTIEON_AUTH_DATA" | base64 -w 0)
nextflow secrets set SENTIEON_AUTH_DATA_BASE64 $SENTIEON_AUTH_DATA_BASE64

- name: Conda clean
if: matrix.profile == 'conda'
run: conda clean -a
Expand Down
104 changes: 104 additions & 0 deletions bin/license_message.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env python3

"""
Functions for generating and sending license messages
"""

# Modified from - https://stackoverflow.com/a/59835994

import argparse
import base64
import calendar
import re
import secrets
import sys

from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from datetime import datetime as dt

MESSAGE_TIMEOUT = 60 * 60 * 24 # Messages are valid for 1 day
NONCE_BYTES = 12


class DecryptionTimeout(Exception):
# Decrypting a message that is too old
pass


def generate_key():
key = secrets.token_bytes(32)
return key


def handle_generate_key(args):
key = generate_key()
key_b64 = base64.b64encode(key)
print(key_b64.decode("utf-8"), file=args.outfile)


def encrypt_message(key, message):
nonce = secrets.token_bytes(NONCE_BYTES)
timestamp = calendar.timegm(dt.now().utctimetuple())
data = timestamp.to_bytes(10, byteorder="big") + b"__" + message
ciphertext = nonce + AESGCM(key).encrypt(nonce, data, b"")
return ciphertext


def handle_encrypt_message(args):
key = base64.b64decode(args.key.encode("utf-8"))
message = args.message.encode("utf-8")
ciphertext = encrypt_message(key, message)
ciphertext_b64 = base64.b64encode(ciphertext)
print(ciphertext_b64.decode("utf-8"), file=args.outfile)


def decrypt_message(key, ciphertext, timeout=MESSAGE_TIMEOUT):
nonce, ciphertext = ciphertext[:NONCE_BYTES], ciphertext[NONCE_BYTES:]
message = AESGCM(key).decrypt(nonce, ciphertext, b"")

msg_timestamp, message = re.split(b"__", message, maxsplit=1)
msg_timestamp = int.from_bytes(msg_timestamp, byteorder="big")
timestamp = calendar.timegm(dt.now().utctimetuple())
if (timestamp - msg_timestamp) > timeout:
raise DecryptionTimeout("The message has an expired timeout")
return message.decode("utf-8")


def handle_decrypt_message(args):
key = base64.b64decode(args.key.encode("utf-8"))
ciphertext = base64.b64decode(args.message.encode("utf-8"))
message = decrypt_message(key, ciphertext, timeout=args.timeout)
print(str(message), file=args.outfile)


def parse_args(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--outfile", default=sys.stdout, type=argparse.FileType("w"), help="The output file")

subparsers = parser.add_subparsers(help="Available sub-commands")

gen_parser = subparsers.add_parser("generate_key", help="Generate a random key string")
gen_parser.set_defaults(func=handle_generate_key)

encrypt_parser = subparsers.add_parser("encrypt", help="Encrypt a message")
encrypt_parser.add_argument("--key", required=True, help="The encryption key")
encrypt_parser.add_argument("--message", required=True, help="Message to encrypt")
encrypt_parser.set_defaults(func=handle_encrypt_message)

decrypt_parser = subparsers.add_parser("decrypt", help="Decyrpt a message")
decrypt_parser.add_argument("--key", required=True, help="The encryption key")
decrypt_parser.add_argument("--message", required=True, help="Message to decrypt")
decrypt_parser.add_argument(
"--timeout",
default=MESSAGE_TIMEOUT,
type=int,
help="A message timeout. Decryption will fail for older messages",
)
decrypt_parser.set_defaults(func=handle_decrypt_message)

return parser.parse_args(argv)


if __name__ == "__main__":
args = parse_args()
args.func(args)
5 changes: 5 additions & 0 deletions conf/modules/aligner.config
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ process {
ext.args = { "--RGSM ${meta.patient}_${meta.sample} --RGID ${meta.read_group}" }
}

withName: "SENTIEON_BWAMEM" {
ext.when = { params.aligner == "sentieon-bwamem" }
ext.args = { "-R ${meta.read_group}" }
}

withName: "(BWAMEM.*_MEM|DRAGMAP_ALIGN)" {
// Markduplicates Spark NEEDS name-sorted reads or runtime goes through the roof
// However if it's skipped, reads need to be coordinate-sorted
Expand Down
10 changes: 10 additions & 0 deletions conf/modules/prepare_genome.config
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ process {
]
}

withName: 'SENTIEON_BWAINDEX' {
ext.when = { !params.sentieon && params.step == "mapping" && params.aligner == "sentieon-bwamem" }
asp8200 marked this conversation as resolved.
Show resolved Hide resolved
publishDir = [
enabled: (params.save_reference || params.build_only_index),
mode: params.publish_dir_mode,
path: { "${params.outdir}/reference" },
pattern: "bwa"
]
}

withName: 'DRAGMAP_HASHTABLE' {
ext.when = { !params.dragmap && params.step == "mapping" && params.aligner == "dragmap" }
publishDir = [
Expand Down
5 changes: 5 additions & 0 deletions conf/test/test.config
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ params {
}

process {
withLabel: 'sentieon' {
ext.sentieon_auth_mech_base64 = secrets.SENTIEON_AUTH_MECH_BASE64
ext.sentieon_auth_data_base64 = secrets.SENTIEON_AUTH_DATA_BASE64
}

withName:'.*:FREEC_SOMATIC'{
ext.args = {
[
Expand Down
10 changes: 10 additions & 0 deletions modules.json
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,16 @@
"git_sha": "c8e35eb2055c099720a75538d1b8adb3fb5a464c",
"installed_by": ["modules"]
},
"sentieon/bwaindex": {
"branch": "master",
"git_sha": "61448300449d4d14ee437ad37bf1853ce6b91147",
"installed_by": ["modules"]
},
"sentieon/bwamem": {
"branch": "master",
"git_sha": "8c159ebb28cfa08890042a133bfab78de932eff7",
"installed_by": ["modules"]
},
"snpeff/download": {
"branch": "master",
"git_sha": "aeefdd170be4583012816212f1345fbebb61ccd6",
Expand Down
57 changes: 57 additions & 0 deletions modules/nf-core/sentieon/bwaindex/main.nf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 41 additions & 0 deletions modules/nf-core/sentieon/bwaindex/meta.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions modules/nf-core/sentieon/bwamem/main.nf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading