Files
languageservices/workflow-parser/src/model/converter/container.ts
T

111 lines
3.5 KiB
TypeScript
Raw Normal View History

2023-01-09 19:02:19 -05:00
import {TemplateContext} from "../../templates/template-context";
import {MappingToken, SequenceToken, StringToken, TemplateToken} from "../../templates/tokens";
import {isString} from "../../templates/tokens/type-guards";
import {Container, Credential} from "../workflow-template";
2023-01-09 19:02:19 -05:00
export function convertToJobContainer(context: TemplateContext, container: TemplateToken): Container | undefined {
let image: StringToken | undefined;
let env: MappingToken | undefined;
let ports: SequenceToken | undefined;
let volumes: SequenceToken | undefined;
let options: StringToken | undefined;
// Skip validation for expressions for now to match
// behavior of the other parsers
2023-03-17 11:17:18 -04:00
for (const [, token] of TemplateToken.traverse(container)) {
if (token.isExpression) {
2023-01-09 19:02:19 -05:00
return;
}
}
if (isString(container)) {
// Workflow uses shorthand syntax `container: image-name`
2023-01-09 19:02:19 -05:00
image = container.assertString("container item");
return {image: image};
}
2023-01-09 19:02:19 -05:00
const mapping = container.assertMapping("container item");
if (mapping)
for (const item of mapping) {
2023-01-09 19:02:19 -05:00
const key = item.key.assertString("container item key");
const value = item.value;
switch (key.value) {
case "image":
2023-01-09 19:02:19 -05:00
image = value.assertString("container image");
break;
case "credentials":
2023-01-09 19:02:19 -05:00
convertToJobCredentials(context, value);
break;
case "env":
2023-01-09 19:02:19 -05:00
env = value.assertMapping("container env");
for (const envItem of env) {
2023-01-09 19:02:19 -05:00
envItem.key.assertString("container env value");
}
2023-01-09 19:02:19 -05:00
break;
case "ports":
2023-01-09 19:02:19 -05:00
ports = value.assertSequence("container ports");
for (const port of ports) {
2023-01-09 19:02:19 -05:00
port.assertString("container port");
}
2023-01-09 19:02:19 -05:00
break;
case "volumes":
2023-01-09 19:02:19 -05:00
volumes = value.assertSequence("container volumes");
for (const volume of volumes) {
2023-01-09 19:02:19 -05:00
volume.assertString("container volume");
}
2023-01-09 19:02:19 -05:00
break;
case "options":
2023-01-09 19:02:19 -05:00
options = value.assertString("container options");
break;
default:
2023-01-09 19:02:19 -05:00
context.error(key, `Unexpected container item key: ${key.value}`);
}
}
if (!image) {
2023-01-09 19:02:19 -05:00
context.error(container, "Container image cannot be empty");
} else {
2023-01-09 19:02:19 -05:00
return {image, env, ports, volumes, options};
}
}
2023-01-09 19:02:19 -05:00
export function convertToJobServices(context: TemplateContext, services: TemplateToken): Container[] | undefined {
const serviceList: Container[] = [];
2023-01-09 19:02:19 -05:00
const mapping = services.assertMapping("services");
for (const service of mapping) {
2023-01-09 19:02:19 -05:00
service.key.assertString("service key");
const container = convertToJobContainer(context, service.value);
if (container) {
2023-01-09 19:02:19 -05:00
serviceList.push(container);
}
}
2023-01-09 19:02:19 -05:00
return serviceList;
}
2023-01-09 19:02:19 -05:00
function convertToJobCredentials(context: TemplateContext, value: TemplateToken): Credential | undefined {
const mapping = value.assertMapping("credentials");
2023-01-09 19:02:19 -05:00
let username: StringToken | undefined;
let password: StringToken | undefined;
for (const item of mapping) {
2023-01-09 19:02:19 -05:00
const key = item.key.assertString("credentials item");
const value = item.value;
switch (key.value) {
case "username":
2023-01-09 19:02:19 -05:00
username = value.assertString("credentials username");
break;
case "password":
2023-01-09 19:02:19 -05:00
password = value.assertString("credentials password");
break;
default:
2023-01-09 19:02:19 -05:00
context.error(key, `credentials key ${key.value}`);
}
}
2023-01-09 19:02:19 -05:00
return {username, password};
}