in provider-utils/awscloudformation/service-walkthroughs/vod-push.js [16:314]
async function serviceQuestions(context, options, defaultValuesFilename, resourceName) {
const { amplify } = context;
const projectMeta = context.amplify.getProjectMeta();
const projectDetails = context.amplify.getProjectDetails();
const defaultLocation = path.resolve(`${__dirname}/../default-values/${defaultValuesFilename}`);
const defaults = JSON.parse(fs.readFileSync(`${defaultLocation}`));
const targetDir = amplify.pathManager.getBackendDirPath();
const props = {};
let oldValues = {};
let nameDict = {};
let aws;
const { payload } = context.parameters.options;
const args = payload ? JSON.parse(payload) : {};
const nameProject = [
{
type: question.resourceName.type,
name: question.resourceName.key,
message: question.resourceName.question,
validate: amplify.inputValidation(question.resourceName),
default: question.resourceName.default,
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.resourceName.key,
value: args.resourceName ? args.resourceName : question.resourceName.default,
});
},
}];
if (resourceName) {
nameDict.resourceName = resourceName;
props.shared = nameDict;
// TODO: find a way of using default values from new question
try {
oldValues = JSON.parse(fs.readFileSync(`${targetDir}/video/${resourceName}/props.json`));
Object.assign(defaults, oldValues);
} catch (err) {
// Do nothing
}
props.shared.bucketInput = defaults.shared.bucketInput;
props.shared.bucketOutput = defaults.shared.bucketOutput;
} else {
nameDict = await inquirer.prompt(nameProject);
props.shared = nameDict;
const uuid = Math.random().toString(36).substring(2, 6)
+ Math.random().toString(36).substring(2, 6);
props.shared.bucketInput = `${nameDict.resourceName.toLowerCase()}-${projectDetails.localEnvInfo.envName}-input-${uuid}`.slice(0, 63);
props.shared.bucketOutput = `${nameDict.resourceName.toLowerCase()}-${projectDetails.localEnvInfo.envName}-output-${uuid}`.slice(0, 63);
}
props.shared.bucket = projectMeta.providers.awscloudformation.DeploymentBucketName;
if (!fs.existsSync(`${targetDir}/video/${props.shared.resourceName}/`)) {
fs.mkdirSync(`${targetDir}/video/${props.shared.resourceName}/`, { recursive: true });
}
props.template = {};
const pluginDir = path.join(`${__dirname}/..`);
const templates = fs.readdirSync(`${pluginDir}/templates/`);
const availableTemplates = [];
templates.forEach((filepath) => {
const templateInfo = JSON.parse(fs.readFileSync(`${pluginDir}/templates/${filepath}`));
availableTemplates.push({
name: templateInfo.Description,
value: filepath,
});
});
props.template.type = {};
availableTemplates.push({
name: 'Bring your own template',
value: 'advanced',
});
const templateQuestion = [
{
type: question.encodingTemplate.type,
name: question.encodingTemplate.key,
message: question.encodingTemplate.question,
choices: availableTemplates,
default: question.encodingTemplate.default,
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.encodingTemplate.key,
value: args.encodingTemplate ? args.encodingTemplate : availableTemplates[0].value,
});
},
},
];
const template = await inquirer.prompt(templateQuestion);
const outputRendition = [];
if (template.encodingTemplate === 'advanced') {
let jobTemplate = {};
while (!('JobTemplate' in jobTemplate)) {
const provider = getAWSConfig(context, options);
aws = await provider.getConfiguredAWSClient(context);
let mcClient = new aws.MediaConvert();
const encodingTemplateName = [
{
type: question.encodingTemplateName.type,
name: question.encodingTemplateName.key,
message: question.encodingTemplateName.question,
validate: amplify.inputValidation(question.encodingTemplateName),
},
];
try {
const endpoints = await mcClient.describeEndpoints().promise();
aws.config.mediaconvert = { endpoint: endpoints.Endpoints[0].Url };
// Override so config applies
mcClient = new aws.MediaConvert();
} catch (e) {
context.print.error(e.message);
}
const advTemplate = await inquirer.prompt(encodingTemplateName);
props.template.name = advTemplate.encodingTemplateName;
const params = {
Name: props.template.name,
};
try {
jobTemplate = await mcClient.getJobTemplate(params).promise();
// Regex: Replaces System- if found at the beginning of the name with ''
jobTemplate.JobTemplate.Name = jobTemplate.JobTemplate.Name.replace(/^(System-)/, '');
delete jobTemplate.JobTemplate.Arn;
delete jobTemplate.JobTemplate.CreatedAt;
delete jobTemplate.JobTemplate.LastUpdated;
delete jobTemplate.JobTemplate.Type;
delete jobTemplate.JobTemplate.StatusUpdateInterval;
delete jobTemplate.JobTemplate.Priority;
fs.outputFileSync(`${targetDir}/video/${props.shared.resourceName}/mediaconvert-job-temp.json`, JSON.stringify(jobTemplate.JobTemplate, null, 4));
} catch (e) {
context.print.error(e.message);
}
// determine the outputRendition of the template (HLS or DASH)
const currentTemplate = jobTemplate.JobTemplate;
for (let counter = 0; counter < currentTemplate.Settings.OutputGroups.length; counter++) {
if (currentTemplate.Settings.OutputGroups[0].OutputGroupSettings.Type.includes('DASH')) {
outputRendition.push('DASH');
} else if (currentTemplate.Settings.OutputGroups[0].OutputGroupSettings.Type.includes('HLS')) {
outputRendition.push('HLS');
}
}
props.template.type = outputRendition;
}
} else {
props.template.name = template.encodingTemplate;
const currentTemplate = JSON.parse(fs.readFileSync(`${pluginDir}/templates/${template.encodingTemplate}`, { encoding: 'utf8', flag: 'r' }));
for (let counter = 0; counter < currentTemplate.Settings.OutputGroups.length; counter++) {
if (currentTemplate.Settings.OutputGroups[counter].OutputGroupSettings.Type.includes('DASH')) {
outputRendition.push('DASH');
} else if (currentTemplate.Settings.OutputGroups[counter].OutputGroupSettings.Type.includes('HLS')) {
outputRendition.push('HLS');
}
}
props.template.type = outputRendition;
fs.copySync(`${pluginDir}/templates/${template.encodingTemplate}`, `${targetDir}/video/${props.shared.resourceName}/mediaconvert-job-temp.json`);
}
const snsQuestion = [
{
type: question.createSnsTopic.type,
name: question.createSnsTopic.key,
message: question.createSnsTopic.question,
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.createSnsTopic.key,
value: args.createSnsTopic
? args.createSnsTopic
: defaults.snsTopic[question.createSnsTopic.key],
});
},
},
];
const sns = await inquirer.prompt(snsQuestion);
props.sns = {};
props.sns.createTopic = sns.createSnsTopic;
if (sns.createSnsTopic) {
const snsFunctionQuestion = [
{
type: question.enableSnsFunction.type,
name: question.enableSnsFunction.key,
message: question.enableSnsFunction.question,
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.enableSnsFunction.key,
value: args.enableSnsFunction
? args.enableSnsFunction
: defaults.snsTopic[question.enableSnsFunction.key],
});
},
},
];
const snsFunction = await inquirer.prompt(snsFunctionQuestion);
props.sns.snsFunction = snsFunction.enableSnsFunction;
}
// prompt for cdn
props.contentDeliveryNetwork = {};
const cdnEnable = [
{
type: question.enableCDN.type,
name: question.enableCDN.key,
message: question.enableCDN.question,
validate: amplify.inputValidation(question.enableCDN),
default: defaults.contentDeliveryNetwork[question.enableCDN.key],
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.enableCDN.key,
value: args.enableCDN
? args.enableCDN
: defaults.contentDeliveryNetwork[question.enableCDN.key],
});
},
}];
const cdnResponse = await inquirer.prompt(cdnEnable);
if (cdnResponse.enableCDN === true) {
const contentDeliveryNetwork = await createCDN(context, props, options, aws, oldValues);
props.contentDeliveryNetwork = contentDeliveryNetwork;
}
props.contentDeliveryNetwork.enableDistribution = cdnResponse.enableCDN;
const cmsEnable = [
{
type: question.enableCMS.type,
name: question.enableCMS.key,
message: question.enableCMS.question,
validate: amplify.inputValidation(question.enableCMS),
default: defaults.contentManagementSystem[question.enableCMS.key],
when(answers) {
return headlessMode.autoAnswer({
context,
answers,
key: question.enableCMS.key,
value: args.enableCMS ? args.enableCMS : false,
});
},
}];
const cmsResponse = await inquirer.prompt(cmsEnable);
props.parameters = {
authRoleName: {
Ref: 'AuthRoleName',
},
};
if (cmsResponse.enableCMS) {
let apiName = getAPIName(context);
if (apiName === '') {
context.print.warning('Video On Demand only supports GraphQL right now.');
context.print.warning('If you want to only use API for CMS then choose the default ToDo and don\'t edit it until later.');
const apiPlugin = amplify.getPluginInstance(context, 'api');
context.input.command = 'add';
await apiPlugin.executeAmplifyCommand(context);
apiName = getAPIName(context);
} else {
context.print.info(`Using ${apiName} to manage API`);
}
await createCMS(context, apiName, props);
props.parameters.GraphQLAPIId = {
'Fn::GetAtt': [
`api${apiName}`,
'Outputs.GraphQLAPIIdOutput',
],
};
props.parameters.GraphQLEndpoint = {
'Fn::GetAtt': [
`api${apiName}`,
'Outputs.GraphQLAPIEndpointOutput',
],
};
}
return props;
}