Skip to content

Commit

Permalink
feat: servicepack deploy command (#133)
Browse files Browse the repository at this point in the history
* feat: servicepack deploy command

* docs: update help

* chore: namme fixes

* chore: refactored command param getters, added tests for command-utils

* chore: fixes

* chore(*): fix formatting, throw error with nonexistent arguments, fix condition for showing example

Co-authored-by: Krishna Acondy <[email protected]>
  • Loading branch information
medjedovicm and krishna-acondy authored Oct 4, 2020
1 parent 58c390b commit e24ef20
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 1 deletion.
11 changes: 10 additions & 1 deletion src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
run,
runRequest,
context,
folderManagement
folderManagement,
servicepack
} from './main'
import { fileExists } from './utils/file-utils'
import path from 'path'
Expand Down Expand Up @@ -82,6 +83,10 @@ function getUnaliasedCommand(command) {
return 'deploy'
}

if (command === 'servicepack') {
return 'servicepack'
}

if (command === 'build-DB' || command === 'DB' || command === 'db') {
return 'db'
}
Expand Down Expand Up @@ -176,6 +181,10 @@ export async function cli(args) {
)
break
}
case 'servicepack': {
await servicepack(command.parameters)
break
}
case 'db': {
await buildDBs(command.parameters[1])
break
Expand Down
14 changes: 14 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { build } from './sasjs-build'
import { deploy } from './sasjs-deploy'
import { processServicepack } from './sasjs-servicepack'
import { buildDB } from './sasjs-db'
import { create } from './sasjs-create'
import { printHelpText } from './sasjs-help'
Expand Down Expand Up @@ -288,6 +289,19 @@ export async function context(command) {
)
}

export async function servicepack(command) {
if (!command)
console.log(
chalk.redBright(`Please provide action for the 'servicepack' command.`)
)

await processServicepack(command).catch((err) =>
console.log(
chalk.redBright('An error has occurred when processing servicepack.', err)
)
)
}

export async function folderManagement(command) {
if (!command)
console.log(
Expand Down
15 changes: 15 additions & 0 deletions src/sasjs-help/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,21 @@ export async function printHelpText() {
NOTE: If no target name is specified/matched, it will build the first target present in config.json.
* ${chalk.greenBright(
'servicepack <command>'
)} - performs operations on Service Packs (collections of jobs & folders).
* ${chalk.cyanBright('deploy')} - deploys service pack from json file.
command example: sasjs servicepack deploy -s ./path/services.json -t targetName
command example: sasjs servicepack deploy --source ./path/services.json --target targetName
NOTE: Providing target name (--target targetName or -t targetName) is optional.
You can force deploy (overwrite an existing deploy) by passing the (-f) flag.
Default target name will be used if target name was omitted.
NOTE: The sasjs servicepack operation is only supported for SAS Viya build targets.
More information available in the online documentation: https://sasjs.io/sasjs-cli-servicepack
* ${chalk.greenBright(
'context <command>'
)} - performs operations on contexts.
Expand Down
122 changes: 122 additions & 0 deletions src/sasjs-servicepack/deploy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import path from 'path'
import SASjs from '@sasjs/adapter/node'
import chalk from 'chalk'
import {
readFile,
folderExists,
createFile,
createFolder
} from '../utils/file-utils'
import { displayResult } from '../utils/displayResult'
import {
getAccessToken,
findTargetInConfiguration
} from '../utils/config-utils'

export async function servicePackDeploy(
jsonFilePath = null,
targetName = null,
isForced = false
) {
console.log({
jsonFilePath,
targetName,
isForced
})

if (path.extname(jsonFilePath) !== '.json') {
throw new Error('Provided data file must be valid json.')
}

const { target, isLocal } = await findTargetInConfiguration(targetName, true)

if (!target.serverType === 'SASVIYA') {
console.log(
chalk.redBright.bold(
`Deployment failed. This commmand is only available on VIYA servers.`
)
)

return
}

console.log(
chalk.cyanBright(`Executing deployServicePack to update SAS server.`)
)

let output = await deployToSasViyaWithServicePack(
jsonFilePath,
target,
isForced
)

let outputPath = path.join(process.cwd(), isLocal ? '/sasjsbuild' : '')

if (!(await folderExists(outputPath))) {
await createFolder(outputPath)
}

outputPath += '/output.json'

await createFile(outputPath, output)

displayResult(
null,
null,
`Request finished. Output is stored at '${outputPath}'`
)
}

async function deployToSasViyaWithServicePack(
jsonFilePath,
buildTarget,
isForced
) {
const sasjs = new SASjs({
serverUrl: buildTarget.serverUrl,
appLoc: buildTarget.appLoc,
serverType: buildTarget.serverType
})

const CONSTANTS = require('../constants')
const buildDestinationFolder = CONSTANTS.buildDestinationFolder

const finalFilePathJSON = path.join(
buildDestinationFolder,
`${buildTarget.name}.json`
)

let jsonContent

if (jsonFilePath) {
jsonContent = await readFile(path.join(process.cwd(), jsonFilePath))
} else {
jsonContent = await readFile(finalFilePathJSON)
}

let jsonObject

try {
jsonObject = JSON.parse(jsonContent)
} catch (err) {
throw new Error('Provided data file must be valid json.')
}

const access_token = await getAccessToken(buildTarget)

if (!access_token) {
console.log(
chalk.redBright.bold(
`Deployment failed. Request is not authenticated.\nRun 'sasjs add' command and provide 'client' and 'secret'.`
)
)
}

return await sasjs.deployServicePack(
jsonObject,
null,
null,
access_token,
isForced
)
}
40 changes: 40 additions & 0 deletions src/sasjs-servicepack/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { servicePackDeploy } from './deploy'
import {
getCommandParameter,
getCommandParameterLastMultiWord,
isFlagPresent
} from '../utils/command-utils'

import chalk from 'chalk'

export async function processServicepack(commandLine) {
const command = commandLine[1]
const commands = {
deploy: 'deploy'
}

if (!commands.hasOwnProperty(command)) {
console.log(
chalk.redBright(
`Not supported servicepack command. Supported commands are:\n${Object.keys(
commands
).join('\n')}`
)
)

return
}

const commandExample =
'sasjs servicepack <command> --source ../viyadeploy.json --target targetName'

switch (command) {
case commands.deploy:
let targetName = getCommandParameterLastMultiWord('-t', '--target', commandLine, commandExample)
let jsonFilePath = getCommandParameter('-s', '--source', commandLine, commandExample)
let isForced = isFlagPresent('-f', commandLine)

servicePackDeploy(jsonFilePath, targetName, isForced)
break
}
}
64 changes: 64 additions & 0 deletions src/utils/command-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import chalk from 'chalk'

export function isFlagPresent(flag, commandLine) {
return commandLine.indexOf(flag) > -1
}

export function getCommandParameter(
commandFlag,
commandFlagLong,
commandLine,
commandExample = ''
) {
let parameterValueFlagIndex = commandLine.indexOf(commandFlagLong)

if (parameterValueFlagIndex === -1)
parameterValueFlagIndex = commandLine.indexOf(commandFlag)

if (parameterValueFlagIndex === -1) {
const errorMessage = chalk.redBright(
`'${commandFlag || commandFlagLong}' flag is missing. ${
commandExample ? "(eg '" + commandExample + "')" : ''
}`
)
throw new Error(errorMessage)

return
}

let parameterValue = commandLine[parameterValueFlagIndex + 1]

return parameterValue
}

export function getCommandParameterLastMultiWord(
commandFlag,
commandFlagLong,
commandLine,
commandExample = ''
) {
let parameterValue = []
let parameterFlagIndex = commandLine.indexOf(commandFlagLong)

if (parameterFlagIndex === -1)
parameterFlagIndex = commandLine.indexOf(commandFlag)

if (parameterFlagIndex !== -1) {
for (let i = parameterFlagIndex + 1; i < commandLine.length; i++) {
if (commandLine[i].includes('-')) {
const errorMessage = `Parameter '${
commandFlagLong || commandFlag
}' has to be provided as the last argument ${
commandExample ? "(eg '" + commandExample + "')" : ''
}`
throw new Error(errorMessage)
}

parameterValue.push(commandLine[i])
}
}

parameterValue = parameterValue.join(' ')

return parameterValue
}
Loading

0 comments on commit e24ef20

Please sign in to comment.