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

Deploy d auth check #33

Merged
merged 6 commits into from
Oct 5, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 12 additions & 13 deletions src/commands/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export enum ParamType {
CommandLine,
Question,
Env,
Default,
}

export interface IParam {
Expand Down Expand Up @@ -148,19 +149,7 @@ export default abstract class Command {
if (this.description) cmd.description(this.description)
if (this.usage) cmd.usage(this.usage)

let options = this.getOptions().filter(opt => opt && opt.name)
const optionAliases: IOptionAliasWithDetails[] = options.reduce(
(acc, opt) => [
...acc,
{ ...opt, aliasTo: opt.name },
...(opt.aliases || [])
.filter(alias => alias && alias.name)
.map(alias => ({ ...alias, aliasTo: opt.name })),
],
[]
)

options = options.filter(opt => !opt.hide)
const options = this.getOptions().filter(opt => opt && opt.name && !opt.hide)
const spaces = ' '.repeat(
options.reduce(
(max, opt) =>
Expand Down Expand Up @@ -204,7 +193,17 @@ export default abstract class Command {
`Positional parameter not supported: ${allParams[0]}\n`,
true
)

const cmdLineOptions = await this.preAction(allParams[0])
const optionAliases: IOptionAliasWithDetails[] = this.getOptions()
.filter(opt => opt && opt.name)
.reduce((acc, opt) => [
...acc,
{ ...opt, aliasTo: opt.name },
...(opt.aliases || [])
.filter(alias => alias && alias.name)
.map(alias => ({ ...alias, aliasTo: opt.name })),
], [])

if (cmdLineOptions)
this.action(await this.getParams(cmdLineOptions, optionAliases))
Expand Down
4 changes: 3 additions & 1 deletion src/commands/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,9 @@ export default class Api extends Command {
: undefined,
},
CliHelper.get().getEnsureAuthenticationOption(
params,
() => this.paramValue(params, K.url),
() => this.paramValue(params, K.pwd),
() => this.paramValue(params, K.name),
async (machine: IMachine) => {
this.machine = machine
try {
Expand Down
76 changes: 59 additions & 17 deletions src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class Deploy extends Command {
'use previously entered values for the current directory, no others options are considered',
when: false,
},
this.getDefaultConfigFileOption(() => this.preQuestions(params!)),
this.getDefaultConfigFileOption(() => this.validateDeploySource(params!)),
{
name: K.url,
char: 'u',
Expand Down Expand Up @@ -110,7 +110,9 @@ export default class Deploy extends Command {
: undefined,
},
CliHelper.get().getEnsureAuthenticationOption(
params,
() => this.paramValue(params, K.url),
() => this.paramValue(params, K.pwd),
() => this.paramValue(params, K.name),
async (machine: IMachine) => {
this.machine = machine
try {
Expand Down Expand Up @@ -205,28 +207,68 @@ export default class Deploy extends Command {
.find((dir: IDeployedDirectory) => dir.cwd === process.cwd())
if (cmdLineoptions[K.default]) {
if (possibleApp && possibleApp.machineNameToDeploy) {
const deployParams: IDeployParams = {
captainMachine: StorageHelper.get().findMachine(
possibleApp.machineNameToDeploy
),
deploySource: possibleApp.deploySource,
appName: possibleApp.appName,
}
if (!deployParams.captainMachine) {
if (!StorageHelper.get().findMachine(possibleApp.machineNameToDeploy)) {
StdOutUtil.printError(
`You have to first login to ${StdOutUtil.getColoredMachineName(
possibleApp.machineNameToDeploy
)} CapRover machine to use previously saved deploy options from this directory with --default.\n`,
true
)
}
await this.deploy(deployParams)
return Promise.resolve(undefined)
this.options = (params?: IParams) => [CliHelper.get().getEnsureAuthenticationOption(
undefined,
undefined,
possibleApp.machineNameToDeploy,
async (machine: IMachine) => {
this.machine = machine
try {
this.apps =
(await CliApiManager.get(machine).getAllApps())
.appDefinitions || []
} catch (e) {
StdOutUtil.printError(
`\nSomething bad happened during deployment to ${StdOutUtil.getColoredMachineName(
machine.name
)}.\n${e.message || e}`,
true
)
}

const appErr = getErrorForAppName(this.apps, possibleApp.appName)
if (appErr !== true)
StdOutUtil.printError(
`\n${appErr || 'Error!'}\n`,
true
)

if (params) {
params[K.app] = {
value: possibleApp.appName,
from: ParamType.Default
}
if (possibleApp.deploySource.branchToPush)
params[K.branch] = {
value: possibleApp.deploySource.branchToPush,
from: ParamType.Default
}
else if (possibleApp.deploySource.tarFilePath)
params[K.tar] = {
value: possibleApp.deploySource.tarFilePath,
from: ParamType.Default
}
else
params[K.img] = {
value: possibleApp.deploySource.imageName,
from: ParamType.Default
}
this.validateDeploySource(params)
}
}
)]
return Promise.resolve({})
} else {
StdOutUtil.printError(
`Can't find previously saved deploy options from this directory, can't use --default.\nFalling back to asking questions...\n\n`,
false
)
StdOutUtil.printError(`Can't find previously saved deploy options from this directory, can't use --default.\n`)
StdOutUtil.printMessage('Falling back to asking questions...\n')
}
} else if (
possibleApp &&
Expand All @@ -244,7 +286,7 @@ export default class Deploy extends Command {
return Promise.resolve(cmdLineoptions)
}

protected preQuestions(params: IParams) {
protected validateDeploySource(params: IParams) {
if (
(this.findParamValue(params, K.branch) ? 1 : 0) +
(this.findParamValue(params, K.tar) ? 1 : 0) +
Expand Down
33 changes: 28 additions & 5 deletions src/commands/serversetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ export default class ServerSetup extends Command {
'Start it by running the following line:'
)
StdOutUtil.printMessage(
'mkdir /captain && docker run -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover'
'docker run -p 80:80 -p 443:443 -p 3000:3000 -v /var/run/docker.sock:/var/run/docker.sock -v /captain:/captain caprover/caprover'
)
StdOutUtil.printMessageAndExit(
'\nPlease read tutorial on CapRover.com to learn how to install CapRover on a server.\n'
StdOutUtil.printMessage(
'\nPlease read tutorial on CapRover.com to learn how to install CapRover on a server.\n',
true
)
}
},
Expand Down Expand Up @@ -116,6 +117,7 @@ export default class ServerSetup extends Command {
aliases: [{ name: 'rootDomain', hide: true }],
type: 'input',
message: 'CapRover server root domain',
when: () => this.checkFreshInstallation(), // Server not already setupped
filter: (domain: string) => Utils.cleanDomain(domain),
validate: (domain: string) =>
domain
Expand Down Expand Up @@ -211,21 +213,42 @@ export default class ServerSetup extends Command {
StdOutUtil.printWarning(
'\nYou may have already setup the server! Use caprover login to log into an existing server.'
)
} else {
StdOutUtil.printWarning(
'\nYou may have specified a wrong IP address or not already started CapRover container on your server!'
)
}
StdOutUtil.errorHandler(e)
return ''
}
}

private async checkFreshInstallation(): Promise<boolean> {
try {
const rootDomain: string = (await CliApiManager.get({
authToken: this.machine.authToken,
baseUrl: `http://${this.ip}:${Constants.SETUP_PORT}`,
name: '',
}).getCaptainInfo()).rootDomain
if (rootDomain)
StdOutUtil.printWarning(
`\nYou may have already setup the server with root domain: ${rootDomain}! Use caprover login to log into an existing server.`,
true
)
} catch (e) {
StdOutUtil.errorHandler(e)
}
return true
}

private async updateRootDomain(rootDomain: string) {
const adminDomain = Utils.cleanAdminDomainUrl(rootDomain, false)!
try {
await CliApiManager.get({
authToken: this.machine.authToken,
baseUrl: `http://${this.ip}:${Constants.SETUP_PORT}`,
name: '',
}).updateRootDomain(rootDomain)
this.machine.baseUrl = adminDomain
this.machine.baseUrl = `http://${Constants.ADMIN_DOMAIN}.${rootDomain}`
} catch (e) {
if (e.captainStatus === ErrorFactory.VERIFICATION_FAILED) {
StdOutUtil.printError(
Expand Down
31 changes: 16 additions & 15 deletions src/utils/CliHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ export default class CliHelper {
}

getEnsureAuthenticationOption(
params?: IParams,
url?: string | (() => string | undefined),
password?: string | (() => string | undefined),
name?: string | (() => string | undefined),
done?: (machine: IMachine) => void
): IOption {
let machine: IMachine
Expand All @@ -189,27 +191,26 @@ export default class CliHelper {
hide: true,
when: async () => {
StdOutUtil.printMessage('Ensuring authentication...')
const url: string | undefined =
params && params.caproverUrl && params.caproverUrl.value
const password: string | undefined =
params &&
params.caproverPassword &&
params.caproverPassword.value
const name: string | undefined =
params && params.caproverName && params.caproverName.value

const getVal = (value?: string | (() => string | undefined)): string | undefined =>
value && value instanceof Function ? value() : value
const _url = getVal(url)
const _password = getVal(password)
const _name = getVal(name)

try {
machine = await CliHelper.get().ensureAuthentication(
url,
password,
name
_url,
_password,
_name
)
return !machine.authToken
} catch (e) {
StdOutUtil.printError(
`\nSomething bad happened during authentication to ${
url
? StdOutUtil.getColoredMachineUrl(url)
: StdOutUtil.getColoredMachineName(name || '')
_url
? StdOutUtil.getColoredMachineUrl(_url)
: StdOutUtil.getColoredMachineName(_name || '')
}.\n${e.message || e}`,
true
)
Expand Down
26 changes: 11 additions & 15 deletions src/utils/StdOutUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,34 @@ import chalk from 'chalk'
import { IMachine } from '../models/storage/StoredObjects'

class StdOutUtils {
printMessage(message: string) {
printMessage(message: string, exit: boolean | number = false) {
console.log(message)
if (exit !== false) process.exit(exit === true ? 0 : exit)
}

printMessageAndExit(message: string) {
console.log(message)
process.exit(0)
}

printGreenMessage(message: string, exit = false) {
printGreenMessage(message: string, exit: boolean | number = false) {
console.log(`${chalk.green(message)}`)
exit && process.exit(0)
if (exit !== false) process.exit(exit === true ? 0 : exit)
}

printMagentaMessage(message: string, exit = false) {
printMagentaMessage(message: string, exit: boolean | number = false) {
console.log(`${chalk.magenta(message)}`)
exit && process.exit(0)
}

printError(error: string, exit = false) {
printError(error: string, exit: boolean | number = false) {
console.log(`${chalk.bold.red(error)}`)
exit && process.exit(0)
if (exit !== false) process.exit(exit === true ? 1 : exit)
}

printWarning(warning: string, exit = false) {
printWarning(warning: string, exit: boolean | number = false) {
console.log(`${chalk.yellow(warning)}`)
exit && process.exit(0)
if (exit !== false) process.exit(exit === true ? 1 : exit)
}

printTip(tip: string, exit = false) {
printTip(tip: string, exit: boolean | number = false) {
console.log(`${chalk.bold.green(tip)}`)
exit && process.exit(0)
if (exit !== false) process.exit(exit === true ? 0 : exit)
}

errorHandler(error: any) {
Expand Down
6 changes: 6 additions & 0 deletions src/utils/StorageHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ export default class StorageHelper {
}

saveDeployedDirectory(directoryToSaveOrUpdate: IDeployedDirectory) {
if (!directoryToSaveOrUpdate ||
!directoryToSaveOrUpdate.appName ||
!directoryToSaveOrUpdate.cwd ||
!directoryToSaveOrUpdate.machineNameToDeploy)
return;

const currDirs = this.getDeployedDirectories()
let updatedDir = false
for (let index = 0; index < currDirs.length; index++) {
Expand Down
17 changes: 10 additions & 7 deletions src/utils/ValidationsHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ const isWindows = process.platform === 'win32'
export function validateIsGitRepository() {
if (!fs.pathExistsSync('./.git')) {
StdOutUtil.printError(
'You are not in a git root directory: this command will only deploys the current directory.\n',
'You are not in a git root directory: this command will only deploys the current directory.\n' +
'Run "caprover deploy --help" to know more deployment options... (e.g. tar file or image name)\n',
true
)
}
if (!commandExistsSync('git')) {
StdOutUtil.printError(
'"git" command not found: CapRover needs "git" to create tar file from your branch source files...\n',
'"git" command not found: CapRover needs "git" to create tar file from your branch source files.\n' +
'Run "caprover deploy --help" to know more deployment options... (e.g. tar file or image name)\n',
true
)
}
Expand Down Expand Up @@ -156,10 +158,10 @@ export function getErrorForAppName(
export function getErrorForBranchName(value: string): true | string {
if (!value || !value.trim()) return 'Please enter branch name.'
value = value.trim()
const cmd = isWindows
? execSync(`git rev-parse ${value} > NUL`)
: execSync(`git rev-parse ${value} 2>/dev/null`)
try {
const cmd = isWindows
? execSync(`git rev-parse ${value} > NUL`)
: execSync(`git rev-parse ${value} 2>/dev/null`)
if (cmd) return true
} catch (e) {}
return `Cannot find hash of last commit on branch "${value}".`
Expand All @@ -173,10 +175,11 @@ export function getErrorForEmail(value: string): true | string {

export function userCancelOperation(cancel: boolean, c?: boolean): boolean {
if (cancel)
StdOutUtil.printMessageAndExit(
StdOutUtil.printMessage(
(c ? '\n' : '') +
'\nOperation cancelled by the user!' +
(!c ? '\n' : '')
(!c ? '\n' : ''),
true
)
return false
}