Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/cdk/apps/core/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ if (customTagsJsonString) {
customTagsMap = JSON.parse(customTagsJsonString);
}

// If user specified adapter custom envs, add them to the stack parameters, so they will be persisted in SSM Parameter Store.
const customWesEnvVarsJsonString = getContextOrDefault<Maybe<string>>(app.node, "CUSTOM_WES_ENV_VARS");
if (customWesEnvVarsJsonString) {
stackParameters.push({
name: "customWesEnvVars",
value: customWesEnvVarsJsonString,
description: "JSON string of custom env vars to be passed to the WES adapter",
});
}

new CoreStack(app, `${PRODUCT_NAME}-Core`, {
vpcId,
bucketName,
Expand Down
14 changes: 14 additions & 0 deletions packages/cdk/lib/env/context-app-parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ export class ContextAppParameters {
* Map of custom tags to be applied to all the infrastructure in the context.
*/
public readonly customTags: { [key: string]: string };
/**
* Map of custom environment variables to be passed to the WES Adapter.
*/
public readonly customWesEnvVars?: { [key: string]: string };

constructor(node: Node) {
const instanceTypeStrings = getEnvStringListOrDefault(node, "BATCH_COMPUTE_INSTANCE_TYPES");
Expand Down Expand Up @@ -142,6 +146,16 @@ export class ContextAppParameters {
} else {
this.customTags = {};
}

const customWesEnvVarsString = getEnvStringOrDefault(node, "CUSTOM_WES_ENV_VARS");

if (customWesEnvVarsString) {
const customWesEnvVars: Array<{ Key: string; Value: string }> = JSON.parse(customWesEnvVarsString);
if (customWesEnvVars && customWesEnvVars.length) {
this.customWesEnvVars = {};
customWesEnvVars.forEach((customWesEnvVar) => (this.customWesEnvVars![customWesEnvVar["Key"]] = customWesEnvVar["Value"]));
}
}
}

public getContextBucketPath(): string {
Expand Down
30 changes: 14 additions & 16 deletions packages/cdk/lib/stacks/engines/cromwell-engine-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export class CromwellEngineConstruct extends EngineConstruct {
contextName: params.contextName,
userId: params.userId,
engineEndpoint: this.engine.loadBalancer.loadBalancerDnsName,
customEnvs: params.customWesEnvVars,
});
this.adapterLogGroup = lambda.logGroup;

Expand Down Expand Up @@ -130,21 +131,18 @@ export class CromwellEngineConstruct extends EngineConstruct {
return engine;
}

private renderAdapterLambda({ role, jobQueueArn, engineLogGroupName, projectName, contextName, userId, engineEndpoint, vpc }) {
return super.renderPythonLambda(
this,
"CromwellWesAdapterLambda",
role,
{
ENGINE_NAME: "cromwell",
ENGINE_ENDPOINT: engineEndpoint,
ENGINE_LOG_GROUP: engineLogGroupName,
JOB_QUEUE: jobQueueArn,
PROJECT_NAME: projectName,
CONTEXT_NAME: contextName,
USER_ID: userId,
},
vpc
);
private renderAdapterLambda({ role, jobQueueArn, engineLogGroupName, projectName, contextName, userId, engineEndpoint, vpc, customEnvs }) {
const environment = {
...customEnvs,
ENGINE_NAME: "cromwell",
ENGINE_ENDPOINT: engineEndpoint,
ENGINE_LOG_GROUP: engineLogGroupName,
JOB_QUEUE: jobQueueArn,
PROJECT_NAME: projectName,
CONTEXT_NAME: contextName,
USER_ID: userId,
};

return super.renderPythonLambda(this, "CromwellWesAdapterLambda", role, environment, vpc);
}
}
24 changes: 11 additions & 13 deletions packages/cdk/lib/stacks/engines/miniwdl-engine-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class MiniwdlEngineConstruct extends EngineConstruct {
jobDefinitionArn: this.miniwdlEngine.headJobDefinition.jobDefinitionArn,
rootDirS3Uri: rootDirS3Uri,
vpc: props.contextParameters.usePublicSubnets ? undefined : props.vpc,
customEnvs: props.contextParameters.customWesEnvVars,
});
this.adapterLogGroup = lambda.logGroup;

Expand Down Expand Up @@ -144,18 +145,15 @@ export class MiniwdlEngineConstruct extends EngineConstruct {
return [this.batchHead.role, this.batchWorkers.role];
}

private renderAdapterLambda({ role, jobQueueArn, jobDefinitionArn, rootDirS3Uri, vpc }) {
return super.renderPythonLambda(
this,
"MiniWDLWesAdapterLambda",
role,
{
ENGINE_NAME: ENGINE_MINIWDL,
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
OUTPUT_DIR_S3_URI: rootDirS3Uri,
},
vpc
);
private renderAdapterLambda({ role, jobQueueArn, jobDefinitionArn, rootDirS3Uri, vpc, customEnvs }) {
const environment = {
...customEnvs,
ENGINE_NAME: ENGINE_MINIWDL,
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
OUTPUT_DIR_S3_URI: rootDirS3Uri,
};

return super.renderPythonLambda(this, "MiniWDLWesAdapterLambda", role, environment, vpc);
}
}
24 changes: 11 additions & 13 deletions packages/cdk/lib/stacks/engines/nextflow-engine-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class NextflowEngineConstruct extends EngineConstruct {
jobDefinitionArn: this.nextflowEngine.headJobDefinition.jobDefinitionArn,
engineLogGroupName: engineLogGroup.logGroupName,
vpc: props.contextParameters.usePublicSubnets ? undefined : props.vpc,
customEnvs: props.contextParameters.customWesEnvVars,
});
this.adapterLogGroup = lambda.logGroup;

Expand All @@ -82,18 +83,15 @@ export class NextflowEngineConstruct extends EngineConstruct {
};
}

private renderAdapterLambda({ role, jobQueueArn, jobDefinitionArn, engineLogGroupName, vpc }) {
return super.renderPythonLambda(
this,
"NextflowWesAdapterLambda",
role,
{
ENGINE_NAME: "nextflow",
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
ENGINE_LOG_GROUP: engineLogGroupName,
},
vpc
);
private renderAdapterLambda({ role, jobQueueArn, jobDefinitionArn, engineLogGroupName, vpc, customEnvs }) {
const environment = {
...customEnvs,
ENGINE_NAME: "nextflow",
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
ENGINE_LOG_GROUP: engineLogGroupName,
};

return super.renderPythonLambda(this, "NextflowWesAdapterLambda", role, environment, vpc);
}
}
32 changes: 15 additions & 17 deletions packages/cdk/lib/stacks/engines/snakemake-engine-construct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ export class SnakemakeEngineConstruct extends EngineConstruct {
taskQueueArn: this.batchWorkers.jobQueue.jobQueueArn,
fsapId: this.snakemakeEngine.fsap.accessPointId,
outputBucket: params.getEngineBucketPath(),
customEnvs: contextParameters.customWesEnvVars,
});
this.adapterLogGroup = lambda.logGroup;

Expand Down Expand Up @@ -173,22 +174,19 @@ export class SnakemakeEngineConstruct extends EngineConstruct {
});
}

private renderAdapterLambda({ vpc, role, jobQueueArn, jobDefinitionArn, taskQueueArn, workflowRoleArn, fsapId, outputBucket }) {
return super.renderPythonLambda(
this,
"SnakemakeWesAdapterLambda",
role,
{
ENGINE_NAME: "snakemake",
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
TASK_QUEUE: taskQueueArn,
WORKFLOW_ROLE: workflowRoleArn,
FSAP_ID: fsapId,
OUTPUT_DIR_S3_URI: outputBucket,
TIME: Date.now().toString(),
},
vpc
);
private renderAdapterLambda({ vpc, role, jobQueueArn, jobDefinitionArn, taskQueueArn, workflowRoleArn, fsapId, outputBucket, customEnvs }) {
const environment = {
...customEnvs,
ENGINE_NAME: "snakemake",
JOB_QUEUE: jobQueueArn,
JOB_DEFINITION: jobDefinitionArn,
TASK_QUEUE: taskQueueArn,
WORKFLOW_ROLE: workflowRoleArn,
FSAP_ID: fsapId,
OUTPUT_DIR_S3_URI: outputBucket,
TIME: Date.now().toString(),
};

return super.renderPythonLambda(this, "SnakemakeWesAdapterLambda", role, environment, vpc);
}
}
28 changes: 15 additions & 13 deletions packages/cli/internal/pkg/cli/context/context_environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,28 @@ type contextEnvironment struct {
AdapterDesignation string
AdapterRepository string

ArtifactBucketName string
ReadBucketArns string
ReadWriteBucketArns string
InstanceTypes string
ResourceType string
MaxVCpus int
ArtifactBucketName string
ReadBucketArns string
ReadWriteBucketArns string
InstanceTypes string
ResourceType string
MaxVCpus int
CustomWesEnvVarsJson string

RequestSpotInstances bool
UsePublicSubnets bool
}

func (input contextEnvironment) ToEnvironmentList() []string {
return environmentMapToList(map[string]string{
"PROJECT": input.ProjectName,
"CONTEXT": input.ContextName,
"USER_ID": input.UserId,
"USER_EMAIL": input.UserEmail,
"OUTPUT_BUCKET": input.OutputBucketName,
"AGC_VERSION": version.Version,
"CUSTOM_TAGS": input.CustomTagsJson,
"PROJECT": input.ProjectName,
"CONTEXT": input.ContextName,
"USER_ID": input.UserId,
"USER_EMAIL": input.UserEmail,
"OUTPUT_BUCKET": input.OutputBucketName,
"AGC_VERSION": version.Version,
"CUSTOM_TAGS": input.CustomTagsJson,
"CUSTOM_WES_ENV_VARS": input.CustomWesEnvVarsJson,

"ENGINE_NAME": input.EngineName,
"FILESYSTEM_TYPE": input.FilesystemType,
Expand Down
8 changes: 8 additions & 0 deletions packages/cli/internal/pkg/cli/context/manager.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package context

import (
"encoding/json"
"fmt"
"net/url"
"strings"
Expand Down Expand Up @@ -214,6 +215,12 @@ func (m *Manager) setContextEnv(contextName string) {
return
}

customWesEnvVarsJsonBytes, err := json.Marshal(m.contextSpec.CustomWesEnvVars)
if err != nil {
m.err = err
return
}

m.contextEnv = contextEnvironment{
ProjectName: m.projectSpec.Name,
ContextName: contextName,
Expand All @@ -225,6 +232,7 @@ func (m *Manager) setContextEnv(contextName string) {
ReadBucketArns: strings.Join(m.readBuckets, listDelimiter),
ReadWriteBucketArns: strings.Join(m.readWriteBuckets, listDelimiter),
InstanceTypes: strings.Join(m.contextSpec.InstanceTypes, listDelimiter),
CustomWesEnvVarsJson: string(customWesEnvVarsJsonBytes),
MaxVCpus: m.contextSpec.MaxVCpus,
RequestSpotInstances: m.contextSpec.RequestSpotInstances,
UsePublicSubnets: m.contextSpec.UsePublicSubnets,
Expand Down
10 changes: 5 additions & 5 deletions packages/cli/internal/pkg/cli/context/manager_deploy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func TestManager_Deploy(t *testing.T) {
mockClients.ssmMock.EXPECT().GetCustomTags().Return(testTags)
mockClients.ecrClientMock.EXPECT().VerifyImageExists(environment.CommonImages["NEXTFLOW"]).Return(nil)
clearContext := mockClients.cdkMock.EXPECT().ClearContext(filepath.Join(testHomeDir, ".agc/cdk/apps/context")).Return(nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(43), testContextName3).After(clearContext).Return(mockClients.progressStream1, nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(44), testContextName3).After(clearContext).Return(mockClients.progressStream1, nil)
displayProgressBar = mockClients.cdkMock.DisplayProgressBar
mockClients.cdkMock.EXPECT().DisplayProgressBar(fmt.Sprintf("Deploying resources for context(s) %s", []string{testContextName3}), []cdk.ProgressStream{mockClients.progressStream1}).Return([]cdk.Result{{Outputs: []string{"some message"}, ExecutionName: testContextName3}})
return mockClients
Expand All @@ -69,7 +69,7 @@ func TestManager_Deploy(t *testing.T) {
mockClients.ssmMock.EXPECT().GetCustomTags().Return("")
mockClients.ecrClientMock.EXPECT().VerifyImageExists(environment.CommonImages["NEXTFLOW"]).Return(nil)
clearContext := mockClients.cdkMock.EXPECT().ClearContext(filepath.Join(testHomeDir, ".agc/cdk/apps/context")).Return(nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(43), testContextName3).After(clearContext).Return(mockClients.progressStream1, nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(44), testContextName3).After(clearContext).Return(mockClients.progressStream1, nil)
displayProgressBar = mockClients.cdkMock.DisplayProgressBar
mockClients.cdkMock.EXPECT().DisplayProgressBar(fmt.Sprintf("Deploying resources for context(s) %s", []string{testContextName3}), []cdk.ProgressStream{mockClients.progressStream1}).Return([]cdk.Result{{Outputs: []string{"some message"}, ExecutionName: testContextName3}})
return mockClients
Expand All @@ -94,8 +94,8 @@ func TestManager_Deploy(t *testing.T) {
mockClients.ecrClientMock.EXPECT().VerifyImageExists(environment.CommonImages["CROMWELL"]).Times(2).Return(nil)
clearContext := mockClients.cdkMock.EXPECT().ClearContext(filepath.Join(testHomeDir, ".agc/cdk/apps/context")).Return(nil)
clearContext2 := mockClients.cdkMock.EXPECT().ClearContext(filepath.Join(testHomeDir, ".agc/cdk/apps/context")).Return(nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(43), testContextName1).After(clearContext).Return(mockClients.progressStream1, nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(43), testContextName2).After(clearContext2).Return(mockClients.progressStream2, nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(44), testContextName1).After(clearContext).Return(mockClients.progressStream1, nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(44), testContextName2).After(clearContext2).Return(mockClients.progressStream2, nil)
displayProgressBar = mockClients.cdkMock.DisplayProgressBar
expectedCdkResult := []cdk.Result{{Outputs: []string{"some message"}, ExecutionName: testContextName1}, {Outputs: []string{"some other message"}, ExecutionName: testContextName2}}
mockClients.cdkMock.EXPECT().DisplayProgressBar(fmt.Sprintf("Deploying resources for context(s) %s", []string{testContextName1, testContextName2}), []cdk.ProgressStream{mockClients.progressStream1, mockClients.progressStream2}).Return(expectedCdkResult)
Expand Down Expand Up @@ -235,7 +235,7 @@ func TestManager_Deploy(t *testing.T) {
mockClients.ssmMock.EXPECT().GetCommonParameter("installed-artifacts/s3-root-url").Return(testArtifactBucket, nil)
mockClients.ssmMock.EXPECT().GetCustomTags().Return(testTags)
mockClients.cdkMock.EXPECT().ClearContext(filepath.Join(testHomeDir, ".agc/cdk/apps/context")).Return(nil)
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(43), testContextName1).Return(nil, fmt.Errorf("some context error"))
mockClients.cdkMock.EXPECT().DeployApp(filepath.Join(testHomeDir, ".agc/cdk/apps/context"), gomock.Len(44), testContextName1).Return(nil, fmt.Errorf("some context error"))
mockClients.ecrClientMock.EXPECT().VerifyImageExists(environment.CommonImages["CROMWELL"]).Return(nil)
return mockClients
},
Expand Down
15 changes: 10 additions & 5 deletions packages/cli/internal/pkg/cli/spec/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,17 @@ type Engine struct {
Engine string `yaml:"engine"`
Filesystem Filesystem `yaml:"filesystem,omitempty"`
}
type CustomWesEnvVar struct {
Key string `yaml:"key"`
Value string `yaml:"value"`
}
type Context struct {
InstanceTypes []string `yaml:"instanceTypes,omitempty"`
RequestSpotInstances bool `yaml:"requestSpotInstances,omitempty"`
MaxVCpus int `yaml:"maxVCpus,omitempty"`
UsePublicSubnets bool `yaml:"usePublicSubnets,omitempty"`
Engines []Engine `yaml:"engines"`
InstanceTypes []string `yaml:"instanceTypes,omitempty"`
RequestSpotInstances bool `yaml:"requestSpotInstances,omitempty"`
MaxVCpus int `yaml:"maxVCpus,omitempty"`
UsePublicSubnets bool `yaml:"usePublicSubnets,omitempty"`
Engines []Engine `yaml:"engines"`
CustomWesEnvVars []CustomWesEnvVar `yaml:"customWesEnvVars"`
}

func (context *Context) UnmarshalYAML(unmarshal func(interface{}) error) error {
Expand Down
21 changes: 21 additions & 0 deletions packages/cli/internal/pkg/cli/spec/project_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,27 @@
},
"required": ["type", "engine"]
}
},
"customWesEnvVars": {
"type":[
"array",
"null"
],
"items": {
"type": "object",
"additionalProperties": false,
"properties": {
"key": {
"type": "string",
"minLength": 1
},
"value": {
"type": "string",
"minLength": 1
}
},
"required": ["key", "value"]
}
}
},
"required": [
Expand Down
Loading