Refactor to serversetup

This commit is contained in:
Daniel Treviño
2018-11-04 21:15:50 +01:00
parent 46949f7dc2
commit ce7b573fe3
11 changed files with 406 additions and 844 deletions
+52 -2
View File
@@ -1,9 +1,59 @@
const MainApi = require("./MainApi")
const SystemApi = require("./SystemApi")
const { DEFAULT_PASSWORD } = require("../utils/constants")
class LoginApi {
loginMachine(url, password) {
constructor() {
this.token = ""
this.oldPassword = DEFAULT_PASSWORD
}
setOldPassword(newPassword) {
this.oldPassword = newPassword
}
setToken(newToken) {
this.token = newToken
}
async loginMachine(baseUrl, password) {
try {
return MainApi.post(url, { password })
const data = await MainApi.post(`${baseUrl}/api/v1/login`, { password })
const dataAsObject = JSON.parse(data)
if (dataAsObject) {
this.setToken(dataAsObject.token)
}
return data
} catch (e) {
throw e
}
}
async changePass(baseUrl, newPassword) {
try {
const customOptions = {
headers: {
"x-captain-auth": LoginApi.token
}
}
const form = {
oldPassword: this.oldPassword,
newPassword
}
const data = await MainApi.post(
`${baseUrl}/api/v1/user/changepassword/`,
form,
customOptions
)
this.setToken(data.token)
SystemApi.setIpAddressOfServer(baseUrl)
return data
} catch (e) {
throw e
}
+66 -15
View File
@@ -1,33 +1,84 @@
const Request = require("request-promise")
class MainApi {
get(url, config) {
return Request.get(url)
}
post(url, form, config) {
const options = {
url,
constructor() {
this.sharedOptions = {
headers: {
"x-namespace": "captain"
},
}
}
}
_buildOptions(options) {
if (!options) return this.sharedOptions
if (options.headers) {
options.headers = Object.assign(
{},
this.sharedOptions.headers,
options.headers
)
}
return Object.assign({}, this.sharedOptions, options)
}
get(url, options) {
const overrideOptions = this._buildOptions(options)
const optionsToSend = {
...overrideOptions,
url,
method: "GET"
}
return Request(optionsToSend)
}
post(url, form, options) {
const overrideOptions = this._buildOptions(options)
const optionsToSend = {
...overrideOptions,
url,
method: "POST",
form
}
return Request(options)
return Request(optionsToSend)
}
put(url, data, config) {
return Request.put(url, data)
put(url, form, options) {
const overrideOptions = this._buildOptions(options)
const optionsToSend = {
...overrideOptions,
url,
method: "PUT",
form
}
return Request(optionsToSend)
}
patch(url, data, config) {
return Request.patch(url, data)
patch(url, form, options) {
const overrideOptions = this._buildOptions(options)
const optionsToSend = {
...overrideOptions,
url,
method: "PATCH",
form
}
return Request(optionsToSend)
}
delete(url, data, config) {
return Request.delete(url)
delete(url, options) {
const overrideOptions = this._buildOptions(options)
const optionsToSend = {
...overrideOptions,
url,
method: "DELETE"
}
return Request(optionsToSend)
}
}
+87
View File
@@ -0,0 +1,87 @@
const MainApi = require("./MainApi")
const LoginApi = require("./LoginApi")
// const spinnerUtil = require("../../utils/spinner")
class SystemApi {
constructor() {
this.ipAddressOfServer = ""
this.customDomainFromUser = ""
this.newPasswordFirstTry = ""
}
setCustomDomainFromUser(newCustomDomainFromUser) {
this.customDomainFromUser = newCustomDomainFromUser
}
setIpAddressOfServer(newIpAddress) {
this.ipAddressOfServer = newIpAddress.trim()
}
async setCustomDomain(baseUrl, rootDomain) {
try {
const customOptions = {
headers: {
"x-captain-auth": LoginApi.token
}
}
const data = await MainApi.post(
`${baseUrl}/api/v1/user/system/changerootdomain/`,
{
rootDomain
},
customOptions
)
return data
} catch (e) {
throw e
}
}
async enableHttps(baseUrl, emailAddress) {
const customOptions = {
headers: {
"x-captain-auth": LoginApi.token
}
}
try {
const data = await MainApi.post(
`${baseUrl}/api/v1/user/system/enablessl/`,
{
emailAddress
},
customOptions
)
return data
} catch (e) {
throw e
}
}
async forceHttps(baseUrl, isEnabled = true) {
try {
const customOptions = {
headers: {
"x-captain-auth": LoginApi.token
}
}
const data = await MainApi.post(
`${baseUrl}/api/v1/user/system/forcessl/`,
{
isEnabled
},
customOptions
)
return data
} catch (e) {
throw e
}
}
}
module.exports = new SystemApi()
+20 -12
View File
@@ -8,24 +8,23 @@ const program = require("commander")
updateNotifier({ pkg: packagejson }).notify({ isGlobal: true })
// Command actions
const list = require("./lib/list")
const logout = require("./lib/logout")
const serversetup = require("./lib/serversetup")
const login = require("./lib/login")
const logout = require("./lib/logout")
const list = require("./lib/list")
// const deploy = require("./lib/deploy")
// Setup
program.version(packagejson.version).description(packagejson.description)
program
.command(
"serversetup",
"Performs necessary actions and prepares your Captain server."
)
.command(
"deploy",
"Deploy your app (current directory) to a specific Captain machine. You'll be prompted to choose your Captain machine."
)
// Commands
program
.command("serversetup")
.description("Performs necessary actions and prepares your Captain server.")
.action(() => {
serversetup()
})
program
.command("login")
.description(
@@ -49,6 +48,15 @@ program
list()
})
program
.command("deploy")
.description(
"Deploy your app (current directory) to a specific Captain machine. You'll be prompted to choose your Captain machine."
)
.action(() => {
// deploy()
})
// Error on unknown commands
program.on("command:*", () => {
const wrongCommands = program.args.join(" ")
+1 -4
View File
@@ -88,10 +88,7 @@ function login() {
const baseUrl = `${handleHttp}${cleanUpUrl(captainAddress)}`
try {
const data = await LoginApi.loginMachine(
`${baseUrl}/api/v1/login`,
captainPassword
)
const data = await LoginApi.loginMachine(baseUrl, captainPassword)
const response = JSON.parse(data)
// TODO - This status should be 200 maybe?
+145 -418
View File
@@ -1,218 +1,18 @@
const program = require("commander")
const chalk = require("chalk")
const MachineHelper = require("../helpers/MachineHelper")
const SystemApi = require("../api/SystemApi")
const LoginApi = require("../api/LoginApi")
const inquirer = require("inquirer")
const configstore = require("configstore")
const request = require("request")
const spinnerUtil = require("./utils/spinner")
const packagejson = require("./package.json")
const configs = new configstore(packagejson.name, {
captainMachines: []
})
program.description("Easy setup for your Captain server.").parse(process.argv)
if (program.args.length) {
console.error(chalk.red("Unrecognized commands:"))
program.args.forEach(function(arg) {
console.log(chalk.red(arg))
})
console.error(chalk.red("This command does not require any options. "))
process.exit(1)
}
function findDefaultCaptainName() {
const machines = configs.get("captainMachines")
let currentSuffix = machines.length + 1
function getCaptainFullName(suffix) {
if (suffix < 10) {
suffix = "0" + suffix
}
return "captain-" + suffix
}
function isSuffixValid(suffixNumber) {
for (let i = 0; i < machines.length; i++) {
const m = machines[i]
if (m.name === getCaptainFullName(suffixNumber)) {
return false
}
}
return true
}
while (!isSuffixValid(currentSuffix)) {
currentSuffix++
}
return getCaptainFullName(currentSuffix)
}
function isIpAddress(ipaddress) {
if (
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
ipaddress
)
) {
return true
}
return false
}
console.log("\nSetup your Captain server\n")
const SAMPLE_IP = "123.123.123.123"
let authTokenFromLogin = null
let ipAddressOfServer = null
let customDomainFromUser = null
let newPasswordFirstTry = null
let oldPassword = "captain42"
function setCustomDomain(baseApiUrl, customDomain) {
return apiEndpointWithLoading("Changing Domain...")(
"POST",
baseApiUrl,
"/api/v1/user/system/changerootdomain/",
{
rootDomain: customDomain
}
)
}
function enableHttps(baseApiUrl, emailAddress) {
return apiEndpointWithLoading("Enabling SSL...")(
"POST",
baseApiUrl,
"/api/v1/user/system/enablessl/",
{
emailAddress: emailAddress
}
)
}
function changePass(baseApiUrl, newPass) {
return apiEndpointWithLoading("Changing Password...")(
"POST",
baseApiUrl,
"/api/v1/user/changepassword/",
{
oldPassword: oldPassword,
newPassword: newPass
}
)
}
function forceHttps(baseApiUrl) {
return apiEndpointWithLoading("Forcing SSL...")(
"POST",
baseApiUrl,
"/api/v1/user/system/forcessl/",
{
isEnabled: true
}
)
}
// returns promise that resolves to auth token
// rejects with ErrorCode or null
function login(baseApiUrl, password) {
return apiEndpointWithLoading("Login...")(
"POST",
baseApiUrl,
"/api/v1/login",
{
password: password
}
).then(function(data) {
return data.token
})
}
function apiEndpointWithLoading(message) {
return (method, baseApiUrl, endpoint, dataToSend) => {
return apiEndpoint(method, baseApiUrl, endpoint, dataToSend, message)
}
}
function apiEndpoint(method, baseApiUrl, endpoint, dataToSend, message) {
const options = {
url: baseApiUrl + endpoint,
headers: {
"x-namespace": "captain",
"x-captain-auth": authTokenFromLogin
},
method: method,
form: dataToSend
}
return new Promise(function(res, rej) {
let spinner
if (message) {
spinner = spinnerUtil.start(message)
}
var callback = function(error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.parse(body)
if (data.status !== 100) {
if (spinner) {
spinnerUtil.fail(spinner)
}
rej(data)
return
}
if (spinner) {
spinnerUtil.succeed(spinner)
}
res(data)
return
}
if (error) {
throw new Error(error)
}
throw new Error(
response ? JSON.stringify(response, null, 2) : "Response NULL"
)
} catch (error) {
if (spinner) {
spinnerUtil.fail(spinner)
}
console.error(
chalk.red(
`Something bad happened. Cannot connect to "${baseApiUrl} ${endpoint}"`
)
)
const errorMessage = error.message ? error.message : error
console.error(`${chalk.red(errorMessage)}\n`)
process.exit(0)
}
}
request(options, callback)
})
}
const { findDefaultCaptainName } = require("../utils/loginHelpers")
const { isIpAddress } = require("../utils/validationsHandler")
const { SAMPLE_IP, DEFAULT_PASSWORD } = require("../utils/constants")
const {
printMessage,
printErrorAndExit,
printError,
printMessageAndExit,
errorHandler
} = require("../utils/messageHandler")
let newPasswordFirstTry = undefined
const questions = [
{
type: "list",
@@ -222,24 +22,18 @@ const questions = [
"\nmkdir /captain && docker run -v /var/run/docker.sock:/var/run/docker.sock dockersaturn/captainduckduck ?",
default: "Yes",
choices: ["Yes", "No"],
filter: function(value) {
return new Promise(function(res, rej) {
if (value === "Yes") {
res(true)
filter: value => {
const answerFromUser = value.trim()
return
}
if (answerFromUser === "Yes") return answerFromUser
console.log(
"\n\nCannot start the setup process if Captain is not installed."
)
printMessage(
"\n\nCannot start the setup process if Captain is not installed."
)
console.log(
"Please read tutorial on CaptainDuckDuck.com\n to learn how to install CaptainDuckDuck on a server.\n"
)
process.exit(0)
})
printMessageAndExit(
"Please read tutorial on CaptainDuckDuck.com to learn how to install CaptainDuckDuck on a server."
)
}
},
{
@@ -247,88 +41,50 @@ const questions = [
default: SAMPLE_IP,
name: "captainAddress",
message: "Enter IP address of your captain server:",
filter: function(value) {
return new Promise(function(res, rej) {
if (value === SAMPLE_IP) {
rej("Enter a valid IP Address")
filter: async value => {
const ipFromUser = value.trim()
return
}
if (ipFromUser === SAMPLE_IP || !isIpAddress(ipFromUser)) {
printErrorAndExit(`\nThis is an invalid IP Address: ${ipFromUser}`)
}
if (!isIpAddress(value.trim())) {
rej("This is an invalid IP Address: " + value)
try {
// login using captain42. and set the ipAddressToServer
const data = await LoginApi.loginMachine(
`http://${ipFromUser}:3000`,
DEFAULT_PASSWORD
)
return
}
SystemApi.setIpAddressOfServer(ipFromUser)
ipAddressOfServer = value.trim()
//login using captain42.
return login("http://" + ipAddressOfServer + ":3000", oldPassword)
.then(function(authTokenFetched) {
authTokenFromLogin = authTokenFetched
res(ipAddressOfServer)
})
.catch(function(error) {
// if error is anything but password wrong, exit here...
if (error.status == 1105) {
authTokenFromLogin = null
res(ipAddressOfServer)
return
}
console.log("")
if (error.status) {
console.log(chalk.red(`Error: ${error.status}`))
console.log(chalk.red(`Error: ${error.description}`))
} else {
console.log(chalk.red(`Error: ${error}`))
}
process.exit(0)
})
})
// All went well
if (data) return ipFromUser
} catch (e) {
errorHandler(e)
}
}
},
{
type: "password",
name: "captainOriginalPassword",
message: "Enter your current password:",
when: function() {
return !authTokenFromLogin
},
filter: function(value) {
return new Promise(function(res, rej) {
console.log("")
when: () => !LoginApi.token,
filter: async value => {
try {
const captainPasswordFromUser = value.trim()
const data = await LoginApi.loginMachine(
`http://${SystemApi.ipAddressOfServer}:3000`,
captainPasswordFromUser
)
return login("http://" + ipAddressOfServer + ":3000", value)
.then(function(authTokenFetched) {
authTokenFromLogin = authTokenFetched
if (data) {
SystemApi.setIpAddressOfServer(captainPasswordFromUser)
oldPassword = value
res(value)
})
.catch(function(error) {
console.log("")
if (error.status) {
console.log(chalk.red("Error: " + error.status))
console.log(chalk.red("Error: " + error.description))
} else {
console.log(chalk.red("Error: " + error))
}
process.exit(0)
})
})
LoginApi.setOldPassword(captainPasswordFromUser)
}
} catch (e) {
errorHandler(e)
}
}
},
{
@@ -338,136 +94,103 @@ const questions = [
"Enter a root domain for this Captain server. For example, enter test.yourdomain.com if you" +
" setup your DNS to point *.test.yourdomain.com to ip address of your server" +
": ",
filter: function(value) {
return new Promise(function(res, rej) {
value = value.trim()
filter: async value => {
try {
const captainRootDomainFromUser = value.trim()
const data = await SystemApi.setCustomDomain(
`http://${SystemApi.ipAddressOfServer}:3000`,
captainRootDomainFromUser
)
customDomainFromUser = "captain." + value
if (data) {
const newCustomDomainFromUser = `captain.${captainRootDomainFromUser}`
return setCustomDomain("http://" + ipAddressOfServer + ":3000", value)
.then(function() {
res(customDomainFromUser)
})
.catch(function(error) {
if (error.status) {
console.log(chalk.red(`Error: ${error.status}`))
SystemApi.setCustomDomainFromUser(newCustomDomainFromUser)
console.log(chalk.red(`Error: ${error.description}`))
} else {
console.log(chalk.red(`Error: ${error}`))
}
process.exit(0)
})
})
return captainRootDomainFromUser
}
} catch (e) {
errorHandler(e)
}
}
},
{
type: "input",
name: "emailAddress",
message: "Enter your 'valid' email address to enable HTTPS: ",
filter: function(value) {
return new Promise(function(res, rej) {
console.log("")
filter: async value => {
try {
const emailAddressFromUser = value.trim()
const { customDomainFromUser } = SystemApi
value = value.trim()
await SystemApi.enableHttps(
`http://${customDomainFromUser}`,
emailAddressFromUser
)
return enableHttps("http://" + customDomainFromUser, value)
.then(function() {
return forceHttps("https://" + customDomainFromUser)
})
.then(function() {
res(value)
})
.catch(function(error) {
console.log("")
const data = await SystemApi.forceHttps(
`https://${customDomainFromUser}`
)
if (error.status) {
console.log(chalk.red(`Error: ${error.status}`))
console.log(chalk.red(`Error: ${error.description}`))
} else {
console.log(chalk.red(`Error: ${error}`))
}
process.exit(0)
})
})
if (data) return emailAddressFromUser
} catch (e) {
errorHandler(e)
}
}
},
{
type: "password",
name: "newPasswordFirstTry",
message: "Enter a new password:",
filter: function(value) {
return new Promise(function(res, rej) {
newPasswordFirstTry = value
filter: value => {
newPasswordFirstTry = value
res(value)
})
return value
}
},
{
type: "password",
name: "newPassword",
message: "Enter a new password:",
filter: function(value) {
return new Promise(function(res, rej) {
if (newPasswordFirstTry !== value) {
rej("Passwords do not match")
//process.exit(0);
filter: async value => {
const { customDomainFromUser } = SystemApi
return
try {
const confirmPasswordValueFromUser = value
const machineUrl = `https://${customDomainFromUser}`
if (newPasswordFirstTry !== confirmPasswordValueFromUser) {
printErrorAndExit("Passwords do not match")
}
return changePass("https://" + customDomainFromUser, value)
.then(function() {
return login("https://" + customDomainFromUser, value)
})
.then(function(token) {
authTokenFromLogin = token
const changePassData = await LoginApi.changePass(
machineUrl,
confirmPasswordValueFromUser
)
res(value)
})
.catch(function(error) {
console.log("")
if (changePassData) {
const loginData = await LoginApi.login(
machineUrl,
confirmPasswordValueFromUser
)
if (error.status) {
console.log(chalk.red(`Error: ${error.status}`))
if (loginData) return
}
} catch (e) {
printError(
"\nIMPORTANT!! Server setup is completed by password is not changed."
)
console.log(chalk.red(`Error: ${error.description}`))
} else {
console.log(chalk.red(`Error: ${error}`))
}
printError("\nYou CANNOT use serversetup anymore. To continue:")
console.log(
chalk.red(
"\nIMPORTANT!! Server setup is completed by password is not changed."
)
)
printError(
`\n- Go to https://${customDomainFromUser} login with default password and change the password in settings.`
)
console.log(
chalk.red("You CANNOT use serversetup anymore. To continue: ")
)
console.log(
chalk.red(
"- Go to https://" +
customDomainFromUser +
" login with default password and change the password in settings."
)
)
console.log(
chalk.red(
"- In terminal (here), type captainduckduck login and enter this as your root domain: " +
customDomainFromUser
)
)
process.exit(0)
})
})
printErrorAndExit(
`\n- In terminal (here), type captainduckduck login and enter this as your root domain: ${customDomainFromUser}`
)
}
}
},
{
@@ -475,14 +198,14 @@ const questions = [
name: "captainName",
message: "Enter a name for this Captain machine:",
default: findDefaultCaptainName(),
validate: function(value) {
const machines = configs.get("captainMachines")
validate: value => {
const newMachineName = value.trim()
for (let i = 0; i < machines.length; i++) {
if (machines[i].name === value) {
return `${value} already exist. If you want to replace the existing entry, you have to first use <logout> command, and then re-login.`
}
}
MachineHelper.machines.map(
machine =>
machine.name === newMachineName &&
`${newMachineName} already exist. If you want to replace the existing entry, you have to first use <logout> command, and then re-login.`
)
if (value.match(/^[-\d\w]+$/i)) {
return true
@@ -493,22 +216,26 @@ const questions = [
}
]
inquirer.prompt(questions).then(function(answers) {
var captainAddress = "https://" + customDomainFromUser
function serversetup() {
printMessage("\nSetup your Captain server\n")
const machines = configs.get("captainMachines")
inquirer.prompt(questions).then(answers => {
var captainAddress = `https://${SystemApi.customDomainFromUser}`
machines.push({
authToken: authTokenFromLogin,
baseUrl: captainAddress,
name: answers.captainName
const newMachine = {
authToken: LoginApi.token,
baseUrl: captainAddress,
name: answers.captainName
}
MachineHelper.addMachine(newMachine)
printMessage(`\n\nCaptain is available at ${captainAddress}`)
printMessage(
"\nFor more details and docs see http://www.captainduckduck.com\n\n"
)
})
}
configs.set("captainMachines", machines)
console.log(`\n\nCaptain is available at ${captainAddress}`)
console.log(
"\nFor more details and docs see http://www.captainduckduck.com\n\n"
)
})
module.exports = serversetup
+3 -1
View File
@@ -1,3 +1,5 @@
const SAMPLE_DOMAIN = "captain.captainroot.yourdomain.com"
const SAMPLE_IP = "123.123.123.123"
const DEFAULT_PASSWORD = "captain42"
module.exports = { SAMPLE_DOMAIN }
module.exports = { SAMPLE_DOMAIN, SAMPLE_IP, DEFAULT_PASSWORD }
-178
View File
@@ -1,178 +0,0 @@
const fs = require("fs-extra")
const chalk = require("chalk")
const request = require("request")
const ProgressBar = require("progress")
const ora = require("ora")
const configstore = require("configstore")
const packagejson = require("./package.json")
const { requestLogin } = require("./utils/loginHandler")
const configs = new configstore(packagejson.name, {
captainMachines: [],
apps: []
})
function sendFileToCaptain(
machineToDeploy,
zipFileFullPath,
appName,
gitHash,
branchToPush
) {
console.log("Uploading file to " + machineToDeploy.baseUrl)
const fileSize = fs.statSync(zipFileFullPath).size
const fileStream = fs.createReadStream(zipFileFullPath)
const barOpts = {
width: 20,
total: fileSize,
clear: true
}
const bar = new ProgressBar(
" uploading [:bar] :percent (ETA :etas)",
barOpts
)
fileStream.on("data", function(chunk) {
bar.tick(chunk.length)
})
let spinner
fileStream.on("end", function() {
console.log(" ")
console.log("This might take several minutes. PLEASE BE PATIENT...")
spinner = ora("Building your source code...").start()
spinner.color = "yellow"
})
const options = {
url:
machineToDeploy.baseUrl +
"/api/v1/user/appData/" +
appName +
"/?detached=1",
headers: {
"x-namespace": "captain",
"x-captain-auth": machineToDeploy.authToken
},
method: "POST",
formData: {
sourceFile: fileStream,
gitHash: gitHash
}
}
function callback(error, response, body) {
if (spinner) {
spinner.stop()
}
if (fs.pathExistsSync(zipFileFullPath) && !getSuppliedTarFile()) {
fs.removeSync(zipFileFullPath)
}
try {
if (!error && response.statusCode === 200) {
const data = JSON.parse(body)
if (data.status === 1106) {
// expired token
requestLogin(
machineToDeploy.name,
machineToDeploy.baseUrl,
function callback(machineToDeployNew) {
deployTo(machineToDeployNew, branchToPush, appName)
}
)
return
}
if (data.status !== 100 && data.status !== 101) {
throw new Error(JSON.stringify(data, null, 2))
}
savePropForDirectory(APP_NAME, appName)
savePropForDirectory(BRANCH_TO_PUSH, branchToPush)
savePropForDirectory(MACHINE_TO_DEPLOY, machineToDeploy)
if (data.status === 100) {
console.log(chalk.green("Deployed successfully: ") + appName)
console.log(" ")
} else if (data.status === 101) {
console.log(chalk.green("Building started: ") + appName)
console.log(" ")
startFetchingBuildLogs(machineToDeploy, appName)
}
return
}
if (error) {
throw new Error(error)
}
throw new Error(
response ? JSON.stringify(response, null, 2) : "Response NULL"
)
} catch (error) {
console.error(
chalk.red('\nSomething bad happened. Cannot deploy "' + appName + '"\n')
)
if (error.message) {
try {
var errorObj = JSON.parse(error.message)
if (errorObj.status) {
console.error(chalk.red("\nError code: " + errorObj.status))
console.error(
chalk.red("\nError message:\n\n " + errorObj.description)
)
} else {
throw new Error("NOT API ERROR")
}
} catch (ignoreError) {
console.error(chalk.red(error.message))
}
} else {
console.error(chalk.red(error))
}
console.log(" ")
}
}
request(options, callback)
}
// Sets default value for propType that is stored in a directory to propValue.
// Replaces saveAppForDirectory
function savePropForDirectory(propType, propValue) {
const apps = configs.get("apps")
for (let i = 0; i < apps.length; i++) {
const app = apps[i]
if (app.cwd === process.cwd()) {
app[propType] = propValue
configs.set("apps", apps)
return
}
}
apps.push({
cwd: process.cwd(),
[propType]: propValue
})
configs.set("apps", apps)
}
module.exports = sendFileToCaptain
-211
View File
@@ -1,211 +0,0 @@
const inquirer = require("inquirer")
const chalk = require("chalk")
const request = require("request")
const configstore = require("configstore")
const packagejson = require("../package.json")
const configs = new configstore(packagejson.name, {
captainMachines: []
})
function requestLogin(serverName, serverAddress, loginCallback) {
console.log("Your auth token is not valid anymore. Try to login again.")
const questions = [
{
type: "password",
name: "captainPassword",
message: "Please enter your password for " + serverAddress,
validate: function(value) {
if (value && value.trim()) {
return true
}
return "Please enter your password for " + serverAddress
}
}
]
function updateAuthTokenInConfigStoreAndReturn(authToken) {
const machines = configs.get("captainMachines")
for (let i = 0; i < machines.length; i++) {
if (machines[i].name === serverName) {
machines[i].authToken = authToken
configs.set("captainMachines", machines)
console.log("You are now logged back in to " + serverAddress)
return machines[i]
}
}
}
inquirer.prompt(questions).then(passwordAnswers => {
var { captainPassword } = passwordAnswers
const options = {
url: serverAddress + "/api/v1/login",
headers: {
"x-namespace": "captain"
},
method: "POST",
form: {
password: captainPassword
}
}
function callback(error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.parse(body)
if (data.status !== 100) {
throw new Error(JSON.stringify(data, null, 2))
}
var newMachineToDeploy = updateAuthTokenInConfigStoreAndReturn(
data.token
)
loginCallback(newMachineToDeploy)
return
}
if (error) {
throw new Error(error)
}
throw new Error(
response ? JSON.stringify(response, null, 2) : "Response NULL"
)
} catch (error) {
if (error.message) {
try {
var errorObj = JSON.parse(error.message)
if (errorObj.status) {
console.error(chalk.red("\nError code: " + errorObj.status))
console.error(
chalk.red("\nError message:\n\n " + errorObj.description)
)
} else {
throw new Error("NOT API ERROR")
}
} catch (ignoreError) {
console.error(chalk.red(error.message))
}
} else {
console.error(chalk.red(error))
}
console.log(" ")
}
process.exit(0)
}
request(options, callback)
})
}
function requestLoginAuth(serverAddress, password, authCallback) {
const options = {
url: serverAddress + "/api/v1/login",
headers: {
"x-namespace": "captain"
},
method: "POST",
form: {
password: password
}
}
function callback(error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.parse(body)
if (data.status !== 100) {
throw new Error(JSON.stringify(data, null, 2))
}
authCallback(data.token)
return
}
if (error) {
throw new Error(error)
}
throw new Error(
response ? JSON.stringify(response, null, 2) : "Response NULL"
)
} catch (error) {
if (error.message) {
try {
var errorObj = JSON.parse(error.message)
if (errorObj.status) {
console.error(chalk.red("\nError code: " + errorObj.status))
console.error(
chalk.red("\nError message:\n\n " + errorObj.description)
)
} else {
throw new Error("NOT API ERROR")
}
} catch (ignoreError) {
console.error(chalk.red(error.message))
}
} else {
console.error(chalk.red(error))
}
console.log(" ")
}
process.exit(0)
}
request(options, callback)
}
function isAuthTokenValid(machineToDeploy, appName, isAuthTokenValidCallback) {
const options = {
url: machineToDeploy.baseUrl + "/api/v1/user/appDefinitions/",
headers: {
"x-namespace": "captain",
"x-captain-auth": machineToDeploy.authToken
},
method: "GET"
}
function callback(error, response, body) {
try {
if (!error && response.statusCode === 200) {
const data = JSON.parse(body)
if (data.status === 1106 || data.status === 1105) {
isAuthTokenValidCallback(false)
} else {
isAuthTokenValidCallback(true)
}
}
} catch (error) {
// This is just a sanity check. We only fire FALSE (i.e. expired) if we know it's expired or password is wrong
isAuthTokenValidCallback(true)
}
}
request(options, callback)
}
module.exports = {
requestLogin,
requestLoginAuth,
isAuthTokenValid
}
+17 -1
View File
@@ -4,6 +4,12 @@ function printMessage(message) {
console.log(message)
}
function printMessageAndExit(message) {
console.log(message)
process.exit(0)
}
function printGreenMessage(message) {
console.log(`${chalk.green(message)}`)
}
@@ -18,9 +24,19 @@ function printErrorAndExit(error) {
process.exit(0)
}
function errorHandler(error) {
if (error.status) {
printErrorAndExit(`\nError: ${error.status}\nError: ${error.description}`)
} else {
printErrorAndExit(`\nError: ${error}`)
}
}
module.exports = {
printMessage,
printMessageAndExit,
printErrorAndExit,
printError,
printGreenMessage
printGreenMessage,
errorHandler
}
+15 -2
View File
@@ -1,5 +1,5 @@
const fs = require("fs-extra")
const { printErrorAndExit } = require("./errorHandler")
const { printErrorAndExit } = require("./messageHandler")
function validateIsGitRepository() {
const gitFolderExists = fs.pathExistsSync("./.git")
@@ -21,7 +21,20 @@ function validateDefinitionFile() {
}
}
function isIpAddress(ipaddress) {
if (
/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(
ipaddress
)
) {
return true
}
return false
}
module.exports = {
validateIsGitRepository,
validateDefinitionFile
validateDefinitionFile,
isIpAddress
}