mirror of https://gitee.com/bigwinds/arangodb
Port Aardvark to FOTF
This commit is contained in:
parent
5a3e42e289
commit
5d765be524
|
@ -1,14 +1,10 @@
|
|||
/*jshint globalstrict: true */
|
||||
/*global applicationContext*/
|
||||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A Foxx.Controller to show all Foxx Applications
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -22,150 +18,117 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
"use strict";
|
||||
const underscore = require('lodash');
|
||||
const cluster = require('@arangodb/cluster');
|
||||
const joi = require('joi');
|
||||
const httperr = require('http-errors');
|
||||
const contentDisposition = require('content-disposition');
|
||||
const internal = require('internal');
|
||||
const db = require('@arangodb').db;
|
||||
const notifications = require('@arangodb/configuration').notifications;
|
||||
const createRouter = require('@arangodb/foxx/router');
|
||||
const NOT_FOUND = require('@arangodb').errors.ERROR_ARANGO_DOCUMENT_NOT_FOUND.code;
|
||||
|
||||
var Foxx = require("@arangodb/foxx");
|
||||
var publicController = new Foxx.Controller(applicationContext);
|
||||
var controller = new Foxx.Controller(applicationContext);
|
||||
var underscore = require("lodash");
|
||||
var cluster = require("@arangodb/cluster");
|
||||
var joi = require("joi");
|
||||
var util = require("util");
|
||||
var internal = require("internal");
|
||||
var contentDisposition = require('content-disposition');
|
||||
var notifications = require("@arangodb/configuration").notifications;
|
||||
var db = require("@arangodb").db;
|
||||
var foxxInstallKey = joi.string().required().description(
|
||||
"The _key attribute, where the information of this Foxx-Install is stored."
|
||||
);
|
||||
const router = createRouter();
|
||||
module.exports = router;
|
||||
|
||||
var foxxes = new (require("./lib/foxxes").Foxxes)();
|
||||
var FoxxManager = require("@arangodb/foxx/manager");
|
||||
var UnauthorizedError = require("http-errors").Unauthorized;
|
||||
|
||||
publicController.activateSessions({
|
||||
autoCreateSession: false,
|
||||
cookie: {name: "arango_sid_" + db._name()}
|
||||
});
|
||||
|
||||
publicController.get("/whoAmI", function(req, res) {
|
||||
var uid = req.session && req.session.get("uid");
|
||||
var user = null;
|
||||
if (uid) {
|
||||
var users = Foxx.getExports("_system/users").userStorage;
|
||||
router.get('/whoAmI', function(req, res) {
|
||||
let user = null;
|
||||
if (internal.options()['server.disable-authentication']) {
|
||||
user = false;
|
||||
} else if (req.session && req.session.uid) {
|
||||
try {
|
||||
user = users.get(uid).get("user");
|
||||
const doc = db._users.document(req.session.uid);
|
||||
user = doc.user;
|
||||
} catch (e) {
|
||||
if (!(e instanceof users.errors.UserNotFound)) {
|
||||
if (!e.isArangoError || e.errorNum !== NOT_FOUND) {
|
||||
throw e;
|
||||
}
|
||||
req.session.setUser(null);
|
||||
req.session.uid = null;
|
||||
}
|
||||
} else if (internal.options()["server.disable-authentication"]) {
|
||||
user = false;
|
||||
}
|
||||
res.json({user: user});
|
||||
res.json({user});
|
||||
});
|
||||
|
||||
publicController.destroySession("/logout", function (req, res) {
|
||||
router.post('/logout', function (req, res) {
|
||||
req.session.uid = null;
|
||||
res.json({success: true});
|
||||
});
|
||||
|
||||
publicController.post("/login", function (req, res) {
|
||||
if (req.session) {
|
||||
req.session.set({uid: null, userDate: null});
|
||||
} else {
|
||||
req.session = publicController.sessions.getSessionStorage().create();
|
||||
router.post('/login', function (req, res) {
|
||||
if (!req.session) {
|
||||
req.session = module.context.sessions.new();
|
||||
}
|
||||
var users = Foxx.getExports("_system/users").userStorage;
|
||||
var credentials = req.parameters.credentials;
|
||||
var user = users.resolve(credentials.get("username"));
|
||||
if (!user) throw new UnauthorizedError();
|
||||
var auth = Foxx.getExports("_system/simple-auth").auth;
|
||||
var valid = auth.verifyPassword(user.get("authData").simple, credentials.get("password"));
|
||||
if (!valid) throw new UnauthorizedError();
|
||||
req.session.setUser(user);
|
||||
req.session.save();
|
||||
res.json({
|
||||
user: user.get("user")
|
||||
});
|
||||
}).bodyParam("credentials", {
|
||||
type: Foxx.Model.extend({
|
||||
username: joi.string().required(),
|
||||
password: joi.string().required()
|
||||
}),
|
||||
description: "Login credentials."
|
||||
});
|
||||
|
||||
publicController.get("/unauthorized", function() {
|
||||
throw new UnauthorizedError();
|
||||
});
|
||||
const doc = db._users.firstExample({user: req.body.username});
|
||||
const valid = module.context.auth.verify(
|
||||
doc ? doc.authData.simple : null,
|
||||
req.body.password
|
||||
);
|
||||
|
||||
publicController.get("/index.html", function(req, res) {
|
||||
var prefix = '/_db/' + encodeURIComponent(req.database) + applicationContext.mount;
|
||||
|
||||
res.status(302);
|
||||
res.set("Location", prefix + "/standalone.html");
|
||||
});
|
||||
|
||||
controller.activateSessions({
|
||||
autoCreateSession: false,
|
||||
cookie: {name: "arango_sid_" + db._name()}
|
||||
});
|
||||
|
||||
controller.allRoutes
|
||||
.errorResponse(UnauthorizedError, 401, "unauthorized")
|
||||
.onlyIf(function (req, res) {
|
||||
if (!internal.options()["server.disable-authentication"] && (!req.session || !req.session.get('uid'))) {
|
||||
throw new UnauthorizedError();
|
||||
if (!valid) {
|
||||
throw new httperr.Unauthorized();
|
||||
}
|
||||
|
||||
const user = doc.user;
|
||||
req.session.uid = doc._key;
|
||||
res.json({user});
|
||||
})
|
||||
.body({
|
||||
username: joi.string().required(),
|
||||
password: joi.string().required().allow('')
|
||||
}, 'Login credentials.');
|
||||
|
||||
router.get('/unauthorized', function() {
|
||||
throw new httperr.Unauthorized();
|
||||
});
|
||||
|
||||
controller.apiDocumentation('/api', {
|
||||
swaggerJson(req, res) {
|
||||
var filename = applicationContext.fileName('api-docs.json');
|
||||
res.sendFile(filename, {lastModified: true});
|
||||
router.get('/index.html', function(req, res) {
|
||||
res.redirect(req.makeAbsolute('standalone.html'));
|
||||
});
|
||||
|
||||
const authRouter = createRouter();
|
||||
router.use(authRouter);
|
||||
|
||||
authRouter.use((req, res, next) => {
|
||||
if (!internal.options()['server.disable-authentication'] && !req.user) {
|
||||
throw new httperr.Unauthorized();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
/** Is version check allowed
|
||||
*
|
||||
* Check if version check is allowed
|
||||
*/
|
||||
controller.get("shouldCheckVersion", function(req, res) {
|
||||
authRouter.get('/api/*', module.context.createSwaggerHandler(
|
||||
(req) => ({
|
||||
appPath: req.queryParams.mount,
|
||||
swaggerJson(req, res) {
|
||||
res.sendFile(module.context.fileName('api-docs.json'), {lastModified: true});
|
||||
}
|
||||
})
|
||||
));
|
||||
|
||||
authRouter.get('shouldCheckVersion', function(req, res) {
|
||||
var versions = notifications.versions();
|
||||
res.json(Boolean(versions && versions.enableVersionNotification));
|
||||
})
|
||||
.summary('Is version check allowed')
|
||||
.description('Check if version check is allowed.');
|
||||
|
||||
if (!versions || versions.enableVersionNotification === false) {
|
||||
res.json(false);
|
||||
} else {
|
||||
res.json(true);
|
||||
}
|
||||
});
|
||||
|
||||
/** Disable version check
|
||||
*
|
||||
* Disable the version check in web interface
|
||||
*/
|
||||
controller.post("disableVersionCheck", function(req, res) {
|
||||
authRouter.post('disableVersionCheck', function(req, res) {
|
||||
notifications.setVersions({
|
||||
enableVersionNotification: false
|
||||
});
|
||||
res.json("ok");
|
||||
});
|
||||
res.json('ok');
|
||||
})
|
||||
.summary('Disable version check')
|
||||
.description('Disable the version check in web interface');
|
||||
|
||||
/** Explains a query
|
||||
*
|
||||
* Explains a query in a more user-friendly way than the query
|
||||
* _api/explain
|
||||
*
|
||||
*/
|
||||
controller.post("/query/explain", function(req, res) {
|
||||
authRouter.post('/query/explain', function(req, res) {
|
||||
|
||||
var explain, query = req.body().query,
|
||||
bindVars = req.body().bindVars;
|
||||
|
@ -173,39 +136,35 @@ controller.post("/query/explain", function(req, res) {
|
|||
if (query.length > 0) {
|
||||
try {
|
||||
if (bindVars) {
|
||||
explain = require("@arangodb/aql/explainer").explain({
|
||||
explain = require('@arangodb/aql/explainer').explain({
|
||||
query: query,
|
||||
bindVars: bindVars
|
||||
}, {colors: false}, false, bindVars);
|
||||
}
|
||||
else {
|
||||
explain = require("@arangodb/aql/explainer").explain(query, {colors: false}, false);
|
||||
explain = require('@arangodb/aql/explainer').explain(query, {colors: false}, false);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
explain = JSON.stringify(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
res.json({msg: explain});
|
||||
|
||||
}).summary("Explains a query")
|
||||
.notes("This function gives useful query information");
|
||||
})
|
||||
.summary('Explains a query')
|
||||
.description('Explains a query in a more user-friendly way than the query_api/explain');
|
||||
|
||||
|
||||
/** Download stored queries
|
||||
*
|
||||
* Download and export all queries from the given username.
|
||||
*
|
||||
*/
|
||||
controller.post("/query/upload/:user", function(req, res) {
|
||||
var user = req.params("user");
|
||||
var queries, userColl, queriesToSave;
|
||||
authRouter.post('/query/upload/:user', function(req, res) {
|
||||
var user = req.params('user');
|
||||
var queries, doc, queriesToSave;
|
||||
|
||||
queries = req.body();
|
||||
userColl = db._users.byExample({"user": user}).toArray()[0];
|
||||
queriesToSave = userColl.userData.queries || [ ];
|
||||
doc = db._users.byExample({'user': user}).toArray()[0];
|
||||
queriesToSave = doc.userData.queries || [ ];
|
||||
|
||||
underscore.each(queries, function(newq) {
|
||||
var found = false, i;
|
||||
|
@ -216,7 +175,7 @@ controller.post("/query/upload/:user", function(req, res) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (! found) {
|
||||
if (!found) {
|
||||
queriesToSave.push(newq);
|
||||
}
|
||||
});
|
||||
|
@ -227,23 +186,18 @@ controller.post("/query/upload/:user", function(req, res) {
|
|||
}
|
||||
};
|
||||
|
||||
var result = db._users.update(userColl, toUpdate, true);
|
||||
var result = db._users.update(doc, toUpdate, true);
|
||||
res.json(result);
|
||||
}).summary("Upload user queries")
|
||||
.notes("This function uploads all given user queries");
|
||||
})
|
||||
.summary('Upload user queries')
|
||||
.description('This function uploads all given user queries');
|
||||
|
||||
/** Download stored queries
|
||||
*
|
||||
* Download and export all queries from the given username.
|
||||
*
|
||||
*/
|
||||
authRouter.get('/query/download/:user', function(req, res) {
|
||||
var user = req.params('user');
|
||||
var result = db._users.byExample({'user': user}).toArray()[0];
|
||||
|
||||
controller.get("/query/download/:user", function(req, res) {
|
||||
var user = req.params("user");
|
||||
var result = db._users.byExample({"user": user}).toArray()[0];
|
||||
|
||||
res.set("Content-Type", "application/json");
|
||||
res.set("Content-Disposition", contentDisposition('queries.json'));
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.set('Content-Disposition', contentDisposition('queries.json'));
|
||||
|
||||
if (result === null || result === undefined) {
|
||||
res.json([]);
|
||||
|
@ -252,20 +206,15 @@ controller.get("/query/download/:user", function(req, res) {
|
|||
res.json(result.userData.queries || []);
|
||||
}
|
||||
|
||||
}).summary("Download all user queries")
|
||||
.notes("This function downloads all user queries from the given user");
|
||||
})
|
||||
.summary('Download stored queries')
|
||||
.description('Download and export all queries from the given username.');
|
||||
|
||||
/** Download a query result
|
||||
*
|
||||
* Download and export all queries from the given username.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.get("/query/result/download/:query", function(req, res) {
|
||||
var query = req.params("query"),
|
||||
authRouter.get('/query/result/download/:query', function(req, res) {
|
||||
var query = req.params('query'),
|
||||
parsedQuery;
|
||||
|
||||
var internal = require("internal");
|
||||
var internal = require('internal');
|
||||
query = internal.base64Decode(query);
|
||||
try {
|
||||
parsedQuery = JSON.parse(query);
|
||||
|
@ -274,31 +223,26 @@ controller.get("/query/result/download/:query", function(req, res) {
|
|||
}
|
||||
|
||||
var result = db._query(parsedQuery.query, parsedQuery.bindVars).toArray();
|
||||
res.set("Content-Type", "application/json");
|
||||
res.set("Content-Disposition", contentDisposition('results.json'));
|
||||
res.set('Content-Type', 'application/json');
|
||||
res.set('Content-Disposition', contentDisposition('results.json'));
|
||||
res.json(result);
|
||||
|
||||
}).summary("Download the result of a query")
|
||||
.notes("This function downloads the result of a user query.");
|
||||
})
|
||||
.summary('Download the result of a query')
|
||||
.description('This function downloads the result of a user query.');
|
||||
|
||||
/** Create sample graphs
|
||||
*
|
||||
* Create one of the given sample graphs.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.post("/graph-examples/create/:name", function(req, res) {
|
||||
var name = req.params("name"), g,
|
||||
examples = require("@arangodb/graph-examples/example-graph.js");
|
||||
authRouter.post('/graph-examples/create/:name', function(req, res) {
|
||||
var name = req.params('name'), g,
|
||||
examples = require('@arangodb/graph-examples/example-graph.js');
|
||||
|
||||
if (name === 'knows_graph') {
|
||||
g = examples.loadGraph("knows_graph");
|
||||
g = examples.loadGraph('knows_graph');
|
||||
}
|
||||
else if (name === 'social') {
|
||||
g = examples.loadGraph("social");
|
||||
g = examples.loadGraph('social');
|
||||
}
|
||||
else if (name === 'routeplanner') {
|
||||
g = examples.loadGraph("routeplanner");
|
||||
g = examples.loadGraph('routeplanner');
|
||||
}
|
||||
|
||||
if (typeof g === 'object') {
|
||||
|
@ -308,16 +252,11 @@ controller.post("/graph-examples/create/:name", function(req, res) {
|
|||
res.json({error: true});
|
||||
}
|
||||
|
||||
}).summary("Create a sample graph")
|
||||
.notes("This function executes the internal scripts to create one example graph.");
|
||||
})
|
||||
.summary('Create sample graphs')
|
||||
.description('Create one of the given sample graphs.');
|
||||
|
||||
/** Store job id's in db
|
||||
*
|
||||
* Create a new job id entry in a specific system database with a given id.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.post("/job", function(req, res) {
|
||||
authRouter.post('/job', function(req, res) {
|
||||
|
||||
if (req.body().id && req.body().collection && req.body().type && req.body().desc) {
|
||||
|
||||
|
@ -336,34 +275,22 @@ controller.post("/job", function(req, res) {
|
|||
res.json(false);
|
||||
}
|
||||
|
||||
}).summary("Store job id of a running job")
|
||||
.notes("This function stores a job id into a system collection.");
|
||||
|
||||
/** Delete all jobs
|
||||
*
|
||||
* Delete an existing job id entry in a specific system database with a given id.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.del("/job/", function(req, res) {
|
||||
})
|
||||
.summary('Store job id of a running job')
|
||||
.description('Create a new job id entry in a specific system database with a given id.');
|
||||
|
||||
authRouter.delete('/job/', function(req, res) {
|
||||
db._frontend.removeByExample({
|
||||
model: 'job'
|
||||
}, true);
|
||||
res.json(true);
|
||||
})
|
||||
.summary('Delete all jobs')
|
||||
.description('Delete all jobs in a specific system database with a given id.');
|
||||
|
||||
}).summary("Store job id of a running job")
|
||||
.notes("This function stores a job id into a system collection.");
|
||||
authRouter.delete('/job/:id', function(req, res) {
|
||||
|
||||
/** Delete a job id
|
||||
*
|
||||
* Delete an existing job id entry in a specific system database with a given id.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.del("/job/:id", function(req, res) {
|
||||
|
||||
var id = req.params("id");
|
||||
var id = req.params('id');
|
||||
|
||||
if (id) {
|
||||
db._frontend.removeByExample({
|
||||
|
@ -375,27 +302,15 @@ controller.del("/job/:id", function(req, res) {
|
|||
res.json(false);
|
||||
}
|
||||
|
||||
}).summary("Store job id of a running job")
|
||||
.notes("This function stores a job id into a system collection.");
|
||||
})
|
||||
.summary('Delete a job id')
|
||||
.description('Delete an existing job id entry in a specific system database with a given id.');
|
||||
|
||||
/** Return all job id's
|
||||
*
|
||||
* Return all job id's which are stored in a system database.
|
||||
*
|
||||
*/
|
||||
|
||||
controller.get("/job", function(req, res) {
|
||||
authRouter.get('/job', function(req, res) {
|
||||
|
||||
var result = db._frontend.all().toArray();
|
||||
res.json(result);
|
||||
|
||||
}).summary("Return all job ids.")
|
||||
.notes("This function returns the job ids of all currently running jobs.");
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Local Variables:
|
||||
/// mode: outline-minor
|
||||
/// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
|
||||
/// End:
|
||||
})
|
||||
.summary('Return all job ids.')
|
||||
.description('This function returns the job ids of all currently running jobs.');
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
/*global applicationContext*/
|
||||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A Foxx.Controller to show all Foxx Applications
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -21,168 +18,145 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
const _ = require('lodash');
|
||||
const dd = require('dedent');
|
||||
const httperr = require('http-errors');
|
||||
const cluster = require('@arangodb/cluster');
|
||||
const createRouter = require('@arangodb/foxx/router');
|
||||
const internal = require('internal');
|
||||
const plans = require('./repositories/plans.js');
|
||||
|
||||
// Initialize a new FoxxController called controller under the urlPrefix: "cluster".
|
||||
var FoxxController = require("@arangodb/foxx").Controller,
|
||||
UnauthorizedError = require("http-errors").Unauthorized,
|
||||
internal = require("internal"),
|
||||
controller = new FoxxController(applicationContext),
|
||||
cluster = require("@arangodb/cluster"),
|
||||
load = require("internal").download,
|
||||
db = require("internal").db,
|
||||
_ = require("lodash");
|
||||
const router = createRouter();
|
||||
module.exports = router;
|
||||
|
||||
controller.activateSessions({
|
||||
autoCreateSession: false,
|
||||
cookie: {name: "arango_sid_" + db._name()}
|
||||
router.use((req, res, next) => {
|
||||
if (!internal.options()['server.disable-authentication'] && !req.user) {
|
||||
throw new httperr.Unauthorized();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
router.get('/amICoordinator', function(req, res) {
|
||||
res.json(cluster.isCoordinator());
|
||||
})
|
||||
.summary('Plan and start a new cluster')
|
||||
.description('This will plan a new cluster with the information given in the body');
|
||||
|
||||
if (cluster.isCluster()) {
|
||||
// only make these functions available in cluster mode!
|
||||
var Communication = require("@arangodb/cluster/agency-communication");
|
||||
var comm = new Communication.Communication();
|
||||
var beats = comm.sync.Heartbeats();
|
||||
var diff = comm.diff.current;
|
||||
var servers = comm.current.DBServers();
|
||||
var dbs = comm.current.Databases();
|
||||
var coords = comm.current.Coordinators();
|
||||
|
||||
router.get("/ClusterType", function(req, res) {
|
||||
// Not yet implemented
|
||||
res.json({
|
||||
type: "symmetricSetup"
|
||||
});
|
||||
})
|
||||
.summary('Get the type of the cluster')
|
||||
.description(dd`
|
||||
Returns a string containing the cluster type
|
||||
Possible anwers:
|
||||
- testSetup
|
||||
- symmetricalSetup
|
||||
- asymmetricalSetup
|
||||
`);
|
||||
|
||||
router.get("/DBServers", function(req, res) {
|
||||
var resList = [],
|
||||
list = servers.getList(),
|
||||
diffList = diff.DBServers(),
|
||||
didBeat = beats.didBeat(),
|
||||
serving = beats.getServing();
|
||||
|
||||
_.each(list, function(v, k) {
|
||||
v.name = k;
|
||||
resList.push(v);
|
||||
if (!_.contains(didBeat, k)) {
|
||||
v.status = "critical";
|
||||
return;
|
||||
}
|
||||
if (v.role === "primary" && !_.contains(serving, k)) {
|
||||
v.status = "warning";
|
||||
return;
|
||||
}
|
||||
v.status = "ok";
|
||||
});
|
||||
_.each(diffList.missing, function(v) {
|
||||
v.status = "missing";
|
||||
resList.push(v);
|
||||
});
|
||||
res.json(resList);
|
||||
})
|
||||
.summary('Get all DBServers')
|
||||
.description('Get a list of all running and expected DBServers within the cluster');
|
||||
|
||||
router.get("/Coordinators", function(req, res) {
|
||||
var resList = [],
|
||||
list = coords.getList(),
|
||||
diffList = diff.Coordinators(),
|
||||
didBeat = beats.didBeat();
|
||||
|
||||
_.each(list, function(v, k) {
|
||||
v.name = k;
|
||||
resList.push(v);
|
||||
if (!_.contains(didBeat, k)) {
|
||||
v.status = "critical";
|
||||
return;
|
||||
}
|
||||
v.status = "ok";
|
||||
});
|
||||
_.each(diffList.missing, function(v) {
|
||||
v.status = "missing";
|
||||
resList.push(v);
|
||||
});
|
||||
res.json(resList);
|
||||
});
|
||||
|
||||
controller.allRoutes
|
||||
.errorResponse(UnauthorizedError, 401, "unauthorized")
|
||||
.onlyIf(function (req, res) {
|
||||
if (!internal.options()["server.disable-authentication"] && (!req.session || !req.session.get('uid'))) {
|
||||
throw new UnauthorizedError();
|
||||
router.get("/Databases", function(req, res) {
|
||||
var list = dbs.getList();
|
||||
res.json(_.map(list, (name) => ({name})));
|
||||
});
|
||||
|
||||
router.get("/:dbname/Collections", function(req, res) {
|
||||
var dbname = req.params("dbname"),
|
||||
selected = dbs.select(dbname);
|
||||
try {
|
||||
res.json(_.map(
|
||||
selected.getCollections(),
|
||||
(name) => ({name})
|
||||
));
|
||||
} catch(e) {
|
||||
res.json([]);
|
||||
}
|
||||
});
|
||||
|
||||
/** Plan and start a new cluster
|
||||
*
|
||||
* This will plan a new cluster with the information
|
||||
* given in the body
|
||||
*/
|
||||
controller.get("/amICoordinator", function(req, res) {
|
||||
res.json(cluster.isCoordinator());
|
||||
router.get("/:dbname/:colname/Shards", function(req, res) {
|
||||
var dbname = req.params("dbname");
|
||||
var colname = req.params("colname");
|
||||
var selected = dbs.select(dbname).collection(colname);
|
||||
res.json(selected.getShardsByServers());
|
||||
});
|
||||
|
||||
if (cluster.isCluster()) {
|
||||
// only make these functions available in cluster mode!
|
||||
var Communication = require("@arangodb/cluster/agency-communication"),
|
||||
comm = new Communication.Communication(),
|
||||
beats = comm.sync.Heartbeats(),
|
||||
diff = comm.diff.current,
|
||||
servers = comm.current.DBServers(),
|
||||
dbs = comm.current.Databases(),
|
||||
coords = comm.current.Coordinators();
|
||||
|
||||
|
||||
/** Get the type of the cluster
|
||||
*
|
||||
* Returns a string containing the cluster type
|
||||
* Possible anwers:
|
||||
* - testSetup
|
||||
* - symmetricalSetup
|
||||
* - asymmetricalSetup
|
||||
*
|
||||
*/
|
||||
controller.get("/ClusterType", function(req, res) {
|
||||
// Not yet implemented
|
||||
res.json({
|
||||
type: "symmetricSetup"
|
||||
});
|
||||
});
|
||||
|
||||
/** Get all DBServers
|
||||
*
|
||||
* Get a list of all running and expected DBServers
|
||||
* within the cluster
|
||||
*/
|
||||
controller.get("/DBServers", function(req, res) {
|
||||
var resList = [],
|
||||
list = servers.getList(),
|
||||
diffList = diff.DBServers(),
|
||||
didBeat = beats.didBeat(),
|
||||
serving = beats.getServing();
|
||||
|
||||
_.each(list, function(v, k) {
|
||||
v.name = k;
|
||||
resList.push(v);
|
||||
if (!_.contains(didBeat, k)) {
|
||||
v.status = "critical";
|
||||
return;
|
||||
}
|
||||
if (v.role === "primary" && !_.contains(serving, k)) {
|
||||
v.status = "warning";
|
||||
return;
|
||||
}
|
||||
v.status = "ok";
|
||||
});
|
||||
_.each(diffList.missing, function(v) {
|
||||
v.status = "missing";
|
||||
resList.push(v);
|
||||
});
|
||||
res.json(resList);
|
||||
});
|
||||
|
||||
controller.get("/Coordinators", function(req, res) {
|
||||
var resList = [],
|
||||
list = coords.getList(),
|
||||
diffList = diff.Coordinators(),
|
||||
didBeat = beats.didBeat();
|
||||
|
||||
_.each(list, function(v, k) {
|
||||
v.name = k;
|
||||
resList.push(v);
|
||||
if (!_.contains(didBeat, k)) {
|
||||
v.status = "critical";
|
||||
return;
|
||||
}
|
||||
v.status = "ok";
|
||||
});
|
||||
_.each(diffList.missing, function(v) {
|
||||
v.status = "missing";
|
||||
resList.push(v);
|
||||
});
|
||||
res.json(resList);
|
||||
});
|
||||
|
||||
controller.get("/Databases", function(req, res) {
|
||||
var list = dbs.getList();
|
||||
res.json(_.map(list, function(d) {
|
||||
return {name: d};
|
||||
}));
|
||||
});
|
||||
|
||||
controller.get("/:dbname/Collections", function(req, res) {
|
||||
var dbname = req.params("dbname"),
|
||||
selected = dbs.select(dbname);
|
||||
try {
|
||||
res.json(_.map(selected.getCollections(),
|
||||
function(c) {
|
||||
return {name: c};
|
||||
})
|
||||
);
|
||||
} catch(e) {
|
||||
res.json([]);
|
||||
}
|
||||
});
|
||||
|
||||
controller.get("/:dbname/:colname/Shards", function(req, res) {
|
||||
var dbname = req.params("dbname"),
|
||||
colname = req.params("colname"),
|
||||
selected = dbs.select(dbname).collection(colname);
|
||||
res.json(selected.getShardsByServers());
|
||||
});
|
||||
|
||||
controller.get("/:dbname/:colname/Shards/:servername", function(req, res) {
|
||||
var dbname = req.params("dbname"),
|
||||
colname = req.params("colname"),
|
||||
servername = req.params("servername"),
|
||||
selected = dbs.select(dbname).collection(colname);
|
||||
res.json(_.map(selected.getShardsForServer(servername),
|
||||
function(c) {
|
||||
return {id: c};
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
} // end isCluster()
|
||||
|
||||
}());
|
||||
router.get("/:dbname/:colname/Shards/:servername", function(req, res) {
|
||||
var dbname = req.params("dbname");
|
||||
var colname = req.params("colname");
|
||||
var servername = req.params("servername");
|
||||
var selected = dbs.select(dbname).collection(colname);
|
||||
res.json(_.map(
|
||||
selected.getShardsForServer(servername),
|
||||
(c) => ({id: c})
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -1,13 +1,10 @@
|
|||
/*global applicationContext*/
|
||||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A Foxx.Controller to generate new FoxxApps
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2014 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2010-2014 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -21,44 +18,41 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var FoxxController = require("@arangodb/foxx").Controller,
|
||||
UnauthorizedError = require("http-errors").Unauthorized,
|
||||
internal = require("internal"),
|
||||
Configuration = require("./models/configuration").Model,
|
||||
controller = new FoxxController(applicationContext),
|
||||
db = require("internal").db,
|
||||
FoxxManager = require("@arangodb/foxx/manager");
|
||||
const joi = require('joi');
|
||||
const httperr = require('http-errors');
|
||||
const internal = require('internal');
|
||||
const FoxxManager = require('@arangodb/foxx/manager');
|
||||
const createRouter = require('@arangodb/foxx/router');
|
||||
|
||||
controller.activateSessions({
|
||||
autoCreateSession: false,
|
||||
cookie: {name: "arango_sid_" + db._name()}
|
||||
});
|
||||
|
||||
controller.allRoutes
|
||||
.errorResponse(UnauthorizedError, 401, "unauthorized")
|
||||
.onlyIf(function (req, res) {
|
||||
if (!internal.options()["server.disable-authentication"] && (!req.session || !req.session.get('uid'))) {
|
||||
throw new UnauthorizedError();
|
||||
}
|
||||
});
|
||||
const router = createRouter();
|
||||
module.exports = router;
|
||||
|
||||
controller.get("/devMode", function(req, res) {
|
||||
res.json(false);
|
||||
});
|
||||
router.use((req, res, next) => {
|
||||
if (!internal.options()['server.disable-authentication'] && !req.user) {
|
||||
throw new httperr.Unauthorized();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
controller.post("/generate", function(req, res) {
|
||||
var conf = req.params("configuration");
|
||||
res.json(FoxxManager.install("EMPTY", "/todo", conf));
|
||||
}).bodyParam("configuration", {
|
||||
description: "The configuration for the template.",
|
||||
type: Configuration
|
||||
});
|
||||
}());
|
||||
router.get('/devMode', (req, res) => res.json(false));
|
||||
|
||||
router.post('/generate', (req, res) => res.json(
|
||||
FoxxManager.install('EMPTY', '/todo', req.body)
|
||||
))
|
||||
.body(joi.object({
|
||||
applicationContext: joi.string().optional(),
|
||||
path: joi.string().optional(),
|
||||
name: joi.string().required(),
|
||||
collectionNames: joi.array().required(),
|
||||
authenticated: joi.boolean().required(),
|
||||
author: joi.string().required(),
|
||||
description: joi.string().required(),
|
||||
license: joi.string().required()
|
||||
}), 'The configuration for the template.');
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
/*global applicationContext */
|
||||
"use strict";
|
||||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A Foxx.Controller to show all Foxx Applications
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -22,407 +18,255 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
(function() {
|
||||
|
||||
var internal = require("internal");
|
||||
var db = require("@arangodb").db;
|
||||
var NotFound = require("http-errors").NotFound;
|
||||
var FoxxController = require("@arangodb/foxx").Controller;
|
||||
var UnauthorizedError = require("http-errors").Unauthorized;
|
||||
var controller = new FoxxController(applicationContext);
|
||||
var ArangoError = require("@arangodb").ArangoError;
|
||||
var FoxxManager = require("@arangodb/foxx/manager");
|
||||
var fmUtils = require("@arangodb/foxx/manager-utils");
|
||||
var actions = require("@arangodb/actions");
|
||||
var joi = require("joi");
|
||||
var marked = require("marked");
|
||||
var highlightAuto = require("highlight.js").highlightAuto;
|
||||
var docu = require("./lib/swagger").Swagger;
|
||||
var underscore = require("lodash");
|
||||
var contentDisposition = require('content-disposition');
|
||||
var mountPoint = {
|
||||
type: joi.string().required().description(
|
||||
"The mount point of the app. Has to be url-encoded."
|
||||
)
|
||||
};
|
||||
var scriptName = {
|
||||
type: joi.string().required().description(
|
||||
"The name of an app's script to run."
|
||||
)
|
||||
};
|
||||
var fs = require("fs");
|
||||
var defaultThumb = require("./lib/defaultThumbnail").defaultThumb;
|
||||
const fs = require('fs');
|
||||
const joi = require('joi');
|
||||
const marked = require('marked');
|
||||
const httperr = require('http-errors');
|
||||
const internal = require('internal');
|
||||
const highlightAuto = require('highlight.js').highlightAuto;
|
||||
const FoxxManager = require('@arangodb/foxx/manager');
|
||||
const fmUtils = require('@arangodb/foxx/manager-utils');
|
||||
const createRouter = require('@arangodb/foxx/router');
|
||||
|
||||
controller.activateSessions({
|
||||
autoCreateSession: false,
|
||||
cookie: {name: "arango_sid_" + db._name()}
|
||||
const DEFAULT_THUMBNAIL = module.context.fileName('default-thumbnail.png');
|
||||
|
||||
const mountSchema = joi.string().required().description(
|
||||
'The mount point of the service. Has to be url-encoded.'
|
||||
);
|
||||
|
||||
const router = createRouter();
|
||||
module.exports = router;
|
||||
|
||||
router.use((req, res, next) => {
|
||||
if (!internal.options()['server.disable-authentication'] && !req.user) {
|
||||
throw new httperr.Unauthorized();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
function installApp(req, res, appInfo, options) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var upgrade = req.params('upgrade');
|
||||
var replace = req.params('replace');
|
||||
var service;
|
||||
if (upgrade) {
|
||||
service = FoxxManager.upgrade(appInfo, mount, options);
|
||||
} else if (replace) {
|
||||
service = FoxxManager.replace(appInfo, mount, options);
|
||||
} else {
|
||||
service = FoxxManager.install(appInfo, mount, options);
|
||||
}
|
||||
var config = FoxxManager.configuration(mount);
|
||||
res.json({
|
||||
error: false,
|
||||
configuration: config,
|
||||
name: service.name,
|
||||
version: service.version
|
||||
});
|
||||
}
|
||||
|
||||
controller.allRoutes
|
||||
.errorResponse(UnauthorizedError, 401, "unauthorized")
|
||||
.onlyIf(function (req, res) {
|
||||
if (!internal.options()["server.disable-authentication"] && (!req.session || !req.session.get('uid'))) {
|
||||
throw new UnauthorizedError();
|
||||
const installer = createRouter();
|
||||
router.use(installer)
|
||||
.queryParam('mount', mountSchema)
|
||||
.queryParam('upgrade', joi.boolean().default(false).description(
|
||||
'Trigger to upgrade the service installed at the mountpoint. Triggers setup.'
|
||||
))
|
||||
.queryParam('replace', joi.boolean().default(false).description(
|
||||
'Trigger to replace the service installed at the mountpoint. Triggers teardown and setup.'
|
||||
));
|
||||
|
||||
installer.put('/store', function (req, res) {
|
||||
const content = JSON.parse(req.requestBody);
|
||||
const name = content.name;
|
||||
const version = content.version;
|
||||
installApp(req, res, `${name}:${version}`);
|
||||
})
|
||||
.summary('Install a Foxx from the store')
|
||||
.description('Downloads a Foxx from the store and installs it at the given mount.');
|
||||
|
||||
installer.put('/git', function (req, res) {
|
||||
const content = JSON.parse(req.requestBody);
|
||||
const url = content.url;
|
||||
const version = content.version || 'master';
|
||||
installApp(req, res, `git:${url}:${version}`);
|
||||
})
|
||||
.summary('Install a Foxx from Github')
|
||||
.description('Install a Foxx with user/repository and version.');
|
||||
|
||||
installer.put('/generate', function (req, res) {
|
||||
const info = JSON.parse(req.requestBody);
|
||||
installApp(req, res, 'EMPTY', info);
|
||||
})
|
||||
.summary('Generate a new foxx')
|
||||
.description('Generate a new empty foxx on the given mount point');
|
||||
|
||||
installer.put('/zip', function (req, res) {
|
||||
const content = JSON.parse(req.requestBody);
|
||||
const file = content.zipFile;
|
||||
installApp(req, res, file);
|
||||
})
|
||||
.summary('Install a Foxx from temporary zip file')
|
||||
.description('Install a Foxx from the given zip path. This path has to be created via _api/upload');
|
||||
|
||||
router.delete('/', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var runTeardown = req.parameters.teardown;
|
||||
var service = FoxxManager.uninstall(mount, {
|
||||
teardown: runTeardown,
|
||||
force: true
|
||||
});
|
||||
res.json({
|
||||
error: false,
|
||||
name: service.name,
|
||||
version: service.version
|
||||
});
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.queryParam('teardown', joi.boolean().default(true))
|
||||
.summary('Uninstall a Foxx')
|
||||
.description('Uninstall the Foxx at the given mount-point.');
|
||||
|
||||
router.get('/', function (req, res) {
|
||||
const foxxes = FoxxManager.listJson();
|
||||
foxxes.forEach((foxx) => {
|
||||
const readme = FoxxManager.readme(foxx.mount);
|
||||
if (readme) {
|
||||
foxx.readme = marked(readme, {
|
||||
highlight: (code) => highlightAuto(code).value
|
||||
});
|
||||
}
|
||||
});
|
||||
res.json(foxxes);
|
||||
})
|
||||
.summary('List all Foxxes')
|
||||
.description('Get a List of all running foxxes.');
|
||||
|
||||
controller.extend({
|
||||
installer: function() {
|
||||
this.queryParam("mount", mountPoint);
|
||||
this.queryParam("upgrade", {type: joi.boolean().optional().description(
|
||||
"Trigger to upgrade the app installed at the mountpoint. Triggers setup."
|
||||
)});
|
||||
this.queryParam("replace", {type: joi.boolean().optional().description(
|
||||
"Trigger to replace the app installed at the mountpoint. Triggers teardown and setup."
|
||||
)});
|
||||
}
|
||||
});
|
||||
router.get('/thumbnail', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var service = FoxxManager.lookupApp(mount);
|
||||
res.sendFile(service.thumbnail || DEFAULT_THUMBNAIL);
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Get the thumbnail of a Foxx')
|
||||
.description('Request the thumbnail of the given Foxx in order to display it on the screen.');
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SECTION install
|
||||
// ------------------------------------------------------------
|
||||
router.get('/config', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
res.json(FoxxManager.configuration(mount));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Get the configuration for a service')
|
||||
.description('Used to request the configuration options for services');
|
||||
|
||||
var validateMount = function(req) {
|
||||
var mount = req.params("mount");
|
||||
// Validation
|
||||
mount = decodeURIComponent(mount);
|
||||
return mount;
|
||||
};
|
||||
router.patch('/config', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var data = req.body;
|
||||
res.json(FoxxManager.configure(mount, {configuration: data}));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Set the configuration for a service')
|
||||
.description('Used to overwrite the configuration options for services');
|
||||
|
||||
var installApp = function(req, res, appInfo, options) {
|
||||
var mount = validateMount(req);
|
||||
var upgrade = req.params("upgrade") || false;
|
||||
var replace = req.params("replace") || false;
|
||||
var app;
|
||||
if (upgrade) {
|
||||
app = FoxxManager.upgrade(appInfo, mount, options);
|
||||
} else if (replace) {
|
||||
app = FoxxManager.replace(appInfo, mount, options);
|
||||
} else {
|
||||
app = FoxxManager.install(appInfo, mount, options);
|
||||
}
|
||||
var config = FoxxManager.configuration(mount);
|
||||
res.json({
|
||||
error: false,
|
||||
configuration: config,
|
||||
name: app.name,
|
||||
version: app.version
|
||||
});
|
||||
};
|
||||
router.get('/deps', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
res.json(FoxxManager.dependencies(mount));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Get the dependencies for a service')
|
||||
.description('Used to request the dependencies options for services');
|
||||
|
||||
/** Install a Foxx from the store
|
||||
*
|
||||
* Downloads a Foxx from the store and installs it at the given mount
|
||||
*/
|
||||
controller.put("/store", function(req, res) {
|
||||
var content = JSON.parse(req.requestBody),
|
||||
name = content.name,
|
||||
version = content.version;
|
||||
installApp(req, res, name + ":" + version);
|
||||
router.patch('/deps', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var data = req.body;
|
||||
res.json(FoxxManager.updateDeps(mount, {dependencies: data}));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Set the dependencies for a service')
|
||||
.description('Used to overwrite the dependencies options for services');
|
||||
|
||||
router.post('/tests', function (req, res) {
|
||||
var options = req.body;
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
res.json(FoxxManager.runTests(mount, options));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Run tests for a service')
|
||||
.description('Used to run the tests of a service');
|
||||
|
||||
router.post('/scripts/:name', function (req, res) {
|
||||
const mount = decodeURIComponent(req.params('mount'));
|
||||
const name = req.params('name');
|
||||
const argv = req.body;
|
||||
try {
|
||||
res.json(FoxxManager.runScript(name, mount, argv));
|
||||
} catch (e) {
|
||||
throw e.cause || e;
|
||||
}
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.pathParam('name', joi.string().required(), 'The name of a service\'s script to run.')
|
||||
.body('argv', joi.any().default(null), 'Options to pass to the script.')
|
||||
.summary('Run a script for a service')
|
||||
.description('Used to trigger any script of a service');
|
||||
|
||||
router.patch('/setup', function (req, res) {
|
||||
const mount = decodeURIComponent(req.params('mount'));
|
||||
res.json(FoxxManager.runScript('setup', mount));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Trigger setup script for a service')
|
||||
.description('Used to trigger the setup script of a service');
|
||||
|
||||
router.patch('/teardown', function (req, res) {
|
||||
const mount = decodeURIComponent(req.params('mount'));
|
||||
res.json(FoxxManager.runScript('teardown', mount));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Trigger teardown script for a service')
|
||||
.description('Used to trigger the teardown script of a service');
|
||||
|
||||
router.patch('/devel', function (req, res) {
|
||||
const mount = decodeURIComponent(req.params('mount'));
|
||||
const activate = Boolean(req.body);
|
||||
res.json(FoxxManager[activate ? 'development' : 'production'](mount));
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Activate/Deactivate development mode for a service')
|
||||
.description('Used to toggle between production and development mode');
|
||||
|
||||
router.get('/download/zip', function (req, res) {
|
||||
var mount = decodeURIComponent(req.params('mount'));
|
||||
var service = FoxxManager.lookupApp(mount);
|
||||
var dir = fs.join(fs.makeAbsolute(service.root), service.path);
|
||||
var zipPath = fmUtils.zipDirectory(dir);
|
||||
res.download(zipPath, `${service.name}@${service.version}.zip`);
|
||||
})
|
||||
.queryParam('mount', mountSchema)
|
||||
.summary('Download a service as zip archive')
|
||||
.description('Download a foxx service packed in a zip archive');
|
||||
|
||||
router.get('/fishbowl', function (req, res) {
|
||||
FoxxManager.update();
|
||||
res.json(FoxxManager.availableJson());
|
||||
})
|
||||
.summary('List of all foxx services submitted to the Foxx store.')
|
||||
.description('This function contacts the fishbowl and reports which services are available for install');
|
||||
|
||||
router.get('/docs/standalone/*', module.context.createSwaggerHandler(
|
||||
(req) => ({
|
||||
appPath: req.queryParams.mount
|
||||
})
|
||||
.installer();
|
||||
));
|
||||
|
||||
/** Install a Foxx from Github
|
||||
*
|
||||
* Install a Foxx with user/repository and version
|
||||
*/
|
||||
controller.put("/git", function (req, res) {
|
||||
var content = JSON.parse(req.requestBody),
|
||||
url = content.url,
|
||||
version = content.version;
|
||||
installApp(req, res, "git:" + url + ":" + (version || "master"));
|
||||
router.get('/docs/*', module.context.createSwaggerHandler(
|
||||
(req) => ({
|
||||
indexFile: 'index-alt.html',
|
||||
appPath: req.queryParams.mount
|
||||
})
|
||||
.installer();
|
||||
|
||||
/** Generate a new foxx
|
||||
*
|
||||
* Generate a new empty foxx on the given mount point
|
||||
*/
|
||||
controller.put("/generate", function (req, res) {
|
||||
var info = JSON.parse(req.requestBody);
|
||||
installApp(req, res, "EMPTY", info);
|
||||
})
|
||||
.installer();
|
||||
|
||||
/** Install a Foxx from temporary zip file
|
||||
*
|
||||
* Install a Foxx from the given zip path.
|
||||
* This path has to be created via _api/upload
|
||||
*/
|
||||
controller.put("/zip", function (req, res) {
|
||||
var content = JSON.parse(req.requestBody),
|
||||
file = content.zipFile;
|
||||
installApp(req, res, file);
|
||||
})
|
||||
.installer();
|
||||
|
||||
|
||||
/** Uninstall a Foxx
|
||||
*
|
||||
* Uninstall the Foxx at the given mount-point.
|
||||
*/
|
||||
controller.delete("/", function (req, res) {
|
||||
var mount = validateMount(req);
|
||||
var runTeardown = req.parameters.teardown;
|
||||
var app = FoxxManager.uninstall(mount, {
|
||||
teardown: runTeardown,
|
||||
force: true
|
||||
});
|
||||
res.json({
|
||||
error: false,
|
||||
name: app.name,
|
||||
version: app.version
|
||||
});
|
||||
})
|
||||
.queryParam("mount", mountPoint)
|
||||
.queryParam("teardown", joi.boolean().default(true));
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SECTION information
|
||||
// ------------------------------------------------------------
|
||||
|
||||
/** List all Foxxes
|
||||
*
|
||||
* Get a List of all running foxxes
|
||||
*/
|
||||
controller.get('/', function (req, res) {
|
||||
var foxxes = FoxxManager.listJson();
|
||||
foxxes.forEach(function (foxx) {
|
||||
var readme = FoxxManager.readme(foxx.mount);
|
||||
if (readme) {
|
||||
foxx.readme = marked(readme, {
|
||||
highlight(code) {
|
||||
return highlightAuto(code).value;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
res.json(foxxes);
|
||||
});
|
||||
|
||||
/** Get the thumbnail of a Foxx
|
||||
*
|
||||
* Used to request the thumbnail of the given Foxx in order to display it on the screen.
|
||||
*/
|
||||
controller.get("/thumbnail", function (req, res) {
|
||||
res.transformations = [ "base64decode" ];
|
||||
var mount = validateMount(req);
|
||||
var app = FoxxManager.lookupApp(mount);
|
||||
if (app.hasOwnProperty("thumbnail") && app.thumbnail !== null) {
|
||||
res.body = app.thumbnail;
|
||||
} else {
|
||||
res.body = defaultThumb;
|
||||
}
|
||||
|
||||
// evil mimetype detection attempt...
|
||||
var start = require("internal").base64Decode(res.body.substr(0, 8));
|
||||
if (start.indexOf("PNG") !== -1) {
|
||||
res.contentType = "image/png";
|
||||
}
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Get the configuration for an app
|
||||
*
|
||||
* Used to request the configuration options for apps
|
||||
*/
|
||||
controller.get("/config", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
res.json(FoxxManager.configuration(mount));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Set the configuration for an app
|
||||
*
|
||||
* Used to overwrite the configuration options for apps
|
||||
*/
|
||||
controller.patch("/config", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
var data = req.body();
|
||||
res.json(FoxxManager.configure(mount, {configuration: data}));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Get the dependencies for an app
|
||||
*
|
||||
* Used to request the dependencies options for apps
|
||||
*/
|
||||
controller.get("/deps", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
res.json(FoxxManager.dependencies(mount));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Set the dependencies for an app
|
||||
*
|
||||
* Used to overwrite the dependencies options for apps
|
||||
*/
|
||||
controller.patch("/deps", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
var data = req.body();
|
||||
res.json(FoxxManager.updateDeps(mount, {dependencies: data}));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Run tests for an app
|
||||
*
|
||||
* Used to run the tests of an app
|
||||
*/
|
||||
controller.post("/tests", function (req, res) {
|
||||
var options = req.body();
|
||||
var mount = validateMount(req);
|
||||
res.json(FoxxManager.runTests(mount, options));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Run a script for an app
|
||||
*
|
||||
* Used to trigger any script of an app
|
||||
*/
|
||||
controller.post("/scripts/:name", function (req, res) {
|
||||
var mount = validateMount(req);
|
||||
var name = req.params("name");
|
||||
var argv = req.params("argv");
|
||||
try {
|
||||
res.json(FoxxManager.runScript(name, mount, argv));
|
||||
} catch (e) {
|
||||
throw e.cause || e;
|
||||
}
|
||||
})
|
||||
.queryParam("mount", mountPoint)
|
||||
.pathParam("name", scriptName)
|
||||
.bodyParam(
|
||||
"argv",
|
||||
joi.any().default(null)
|
||||
.description('Options to pass to the script.')
|
||||
);
|
||||
|
||||
/** Trigger setup script for an app
|
||||
*
|
||||
* Used to trigger the setup script of an app
|
||||
*/
|
||||
controller.patch("/setup", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
res.json(FoxxManager.runScript("setup", mount));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
|
||||
/** Trigger teardown script for an app
|
||||
*
|
||||
* Used to trigger the teardown script of an app
|
||||
*/
|
||||
controller.patch("/teardown", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
res.json(FoxxManager.runScript("teardown", mount));
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
|
||||
/** Activate/Deactivate development mode for an app
|
||||
*
|
||||
* Used to toggle between production and development mode
|
||||
*/
|
||||
controller.patch("/devel", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
var activate = Boolean(req.body());
|
||||
if (activate) {
|
||||
res.json(FoxxManager.development(mount));
|
||||
} else {
|
||||
res.json(FoxxManager.production(mount));
|
||||
}
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
|
||||
/** Download an app as zip archive
|
||||
*
|
||||
* Download a foxx app packed in a zip archive
|
||||
*/
|
||||
|
||||
controller.get("/download/zip", function(req, res) {
|
||||
var mount = validateMount(req);
|
||||
var app = FoxxManager.lookupApp(mount);
|
||||
var dir = fs.join(fs.makeAbsolute(app.root), app.path);
|
||||
var zipPath = fmUtils.zipDirectory(dir);
|
||||
res.set("Content-Type", "application/octet-stream");
|
||||
res.set("Content-Disposition", contentDisposition(`${app.name}@${app.version}.zip`));
|
||||
res.body = fs.readFileSync(zipPath);
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SECTION store
|
||||
// ------------------------------------------------------------
|
||||
|
||||
/** List all Foxxes in Fishbowl
|
||||
*
|
||||
* Get the information for all Apps availbale in the Fishbowl and ready for download
|
||||
*
|
||||
*/
|
||||
controller.get('/fishbowl', function (req, res) {
|
||||
FoxxManager.update();
|
||||
res.json(FoxxManager.availableJson());
|
||||
}).summary("List of all foxx apps submitted to the fishbowl store.")
|
||||
.notes("This function contacts the fishbowl and reports which apps are available for install")
|
||||
.errorResponse(ArangoError, 503, "Could not connect to store.");
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SECTION documentation
|
||||
// ------------------------------------------------------------
|
||||
|
||||
controller.apiDocumentation('/docs/standalone', function (req, res) {
|
||||
return {
|
||||
appPath: req.parameters.mount
|
||||
};
|
||||
});
|
||||
|
||||
controller.apiDocumentation('/docs', function (req, res) {
|
||||
return {
|
||||
indexFile: 'index-alt.html',
|
||||
appPath: req.parameters.mount
|
||||
};
|
||||
});
|
||||
|
||||
/** Returns the billboard URL for swagger
|
||||
*
|
||||
* Returns the billboard URL for the application mounted
|
||||
* at the given mountpoint
|
||||
*/
|
||||
controller.get('/billboard', function(req, res) {
|
||||
var mount = decodeURIComponent(decodeURIComponent(req.params("mount")));
|
||||
var path = req.protocol + "://" + req.headers.host +
|
||||
"/_db/" + encodeURIComponent(req.database) +
|
||||
"/_admin/aardvark/foxxes/docu";
|
||||
res.json({
|
||||
swaggerVersion: "1.1",
|
||||
basePath: path,
|
||||
apis: [
|
||||
{path: mount}
|
||||
]
|
||||
});
|
||||
})
|
||||
.queryParam("mount", mountPoint);
|
||||
|
||||
/** Returns the generated Swagger JSON description for one foxx
|
||||
*
|
||||
* This function returns the Swagger JSON API description of the foxx
|
||||
* installed under the given mount point.
|
||||
*/
|
||||
controller.get('/docu/*', function(req, res) {
|
||||
var mount = "";
|
||||
underscore.each(req.suffix, function(part) {
|
||||
mount += "/" + part;
|
||||
});
|
||||
res.json(docu(mount));
|
||||
});
|
||||
|
||||
}());
|
||||
));
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const db = require('@arangodb').db;
|
||||
const sessionsMiddleware = require('@arangodb/foxx/sessions');
|
||||
const cookieTransport = require('@arangodb/foxx/sessions/transports/cookie');
|
||||
const collectionStorage = require('@arangodb/foxx/sessions/storages/collection');
|
||||
const auth = require('@arangodb/foxx/auth');
|
||||
|
||||
module.context.sessions = collectionStorage('_sessions');
|
||||
module.context.users = db._collection('_users');
|
||||
module.context.auth = auth('sha256');
|
||||
|
||||
module.context.use(sessionsMiddleware({
|
||||
autoCreate: false,
|
||||
transport: cookieTransport(`arango_sid_${db._name()}`),
|
||||
storage: module.context.sessions
|
||||
}));
|
||||
|
||||
module.context.use(require('./aardvark'));
|
||||
module.context.use('/foxxes', require('./foxxes'));
|
||||
module.context.use('/cluster', require('./cluster'));
|
||||
module.context.use('/statistics', require('./statistics'));
|
||||
module.context.use('/templates', require('./foxxTemplates'));
|
File diff suppressed because one or more lines are too long
|
@ -1,247 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A TODO-List Foxx-Application written for ArangoDB
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
exports.Foxxes = function () {
|
||||
"use strict";
|
||||
|
||||
// Define the Repository
|
||||
var aal = require("internal").db._collection("_tmp_aal"),
|
||||
foxxmanager = require("@arangodb/foxx/manager"),
|
||||
_ = require("lodash"),
|
||||
ArangoError = require("@arangodb").ArangoError,
|
||||
fs = require("fs");
|
||||
|
||||
// Define the functionality to create a new foxx
|
||||
this.store = function (content) {
|
||||
throw {
|
||||
code: 501,
|
||||
message: "To be implemented."
|
||||
};
|
||||
};
|
||||
|
||||
this.thumbnail = function (mount) {
|
||||
var example = aal.firstExample({
|
||||
mount: mount
|
||||
});
|
||||
if (example === undefined || example === null) {
|
||||
return defaultThumb;
|
||||
}
|
||||
var thumb = example.thumbnail;
|
||||
if (thumb === undefined || thumb === null) {
|
||||
thumb = defaultThumb;
|
||||
}
|
||||
return thumb;
|
||||
};
|
||||
|
||||
this.install = function (name, mount, version, options) {
|
||||
if (version) {
|
||||
name = "app:" + name + ":" + version;
|
||||
}
|
||||
return foxxmanager.mount(name, mount, _.extend({}, options, { setup: true }));
|
||||
};
|
||||
|
||||
// Define the functionality to uninstall an installed foxx
|
||||
this.uninstall = function (key) {
|
||||
// key is mountpoint
|
||||
foxxmanager.teardown(key);
|
||||
return foxxmanager.unmount(key);
|
||||
};
|
||||
|
||||
// Define the functionality to deactivate an installed foxx.
|
||||
this.deactivate = function (key) {
|
||||
throw {
|
||||
code: 501,
|
||||
message: "To be implemented."
|
||||
};
|
||||
};
|
||||
|
||||
// Define the functionality to activate an installed foxx.
|
||||
this.activate = function (key) {
|
||||
throw {
|
||||
code: 501,
|
||||
message: "To be implemented."
|
||||
};
|
||||
};
|
||||
|
||||
// Define the functionality to display all foxxes
|
||||
this.viewAll = function () {
|
||||
var result = aal.toArray().concat(foxxmanager.developmentMounts());
|
||||
|
||||
result.forEach(function(r, i) {
|
||||
// inject development flag
|
||||
if (r._key.match(/^dev:/)) {
|
||||
result[i] = _.extend({}, r);
|
||||
result[i].development = true;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Define the functionality to update one foxx.
|
||||
this.update = function (id, content) {
|
||||
throw {
|
||||
code: 501,
|
||||
message: "To be implemented."
|
||||
};
|
||||
};
|
||||
|
||||
this.move = function(key, app, mount, prefix) {
|
||||
var success;
|
||||
try {
|
||||
success = foxxmanager.mount(app, mount, {collectionPrefix: prefix});
|
||||
foxxmanager.unmount(key);
|
||||
} catch (e) {
|
||||
return {
|
||||
error: true,
|
||||
status: 409,
|
||||
message: "Mount-Point already in use"
|
||||
};
|
||||
}
|
||||
return success;
|
||||
};
|
||||
|
||||
// TODO: merge with functionality js/client/modules/@arangodb/foxx/manager.js
|
||||
this.repackZipFile = function (path) {
|
||||
if (! fs.exists(path) || ! fs.isDirectory(path)) {
|
||||
throw "'" + String(path) + "' is not a directory";
|
||||
}
|
||||
|
||||
var tree = fs.listTree(path);
|
||||
var files = [];
|
||||
var i;
|
||||
|
||||
for (i = 0; i < tree.length; ++i) {
|
||||
var filename = fs.join(path, tree[i]);
|
||||
|
||||
if (fs.isFile(filename)) {
|
||||
files.push(tree[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (files.length === 0) {
|
||||
throw "Directory '" + String(path) + "' is empty";
|
||||
}
|
||||
|
||||
var tempFile = fs.getTempFile("downloads", false);
|
||||
|
||||
fs.zipFile(tempFile, path, files);
|
||||
|
||||
return tempFile;
|
||||
};
|
||||
|
||||
// TODO: merge with functionality js/client/modules/@arangodb/foxx/manager.js
|
||||
this.inspectUploadedFile = function (filename) {
|
||||
var console = require("console");
|
||||
|
||||
if (! fs.isFile(filename)) {
|
||||
throw "Unable to find zip file";
|
||||
}
|
||||
|
||||
var i;
|
||||
var path;
|
||||
|
||||
try {
|
||||
path = fs.getTempFile("zip", false);
|
||||
}
|
||||
catch (err1) {
|
||||
console.error("cannot get temp file: %s", String(err1));
|
||||
throw err1;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.unzipFile(filename, path, false, true);
|
||||
}
|
||||
catch (err2) {
|
||||
console.error("cannot unzip file '%s' into directory '%s': %s", filename, path, String(err2));
|
||||
throw err2;
|
||||
}
|
||||
|
||||
// .............................................................................
|
||||
// locate the manifest file
|
||||
// .............................................................................
|
||||
|
||||
var tree = fs.listTree(path).sort(function(a,b) {
|
||||
return a.length - b.length;
|
||||
});
|
||||
|
||||
var found;
|
||||
var mf = "manifest.json";
|
||||
var re = /[\/\\\\]manifest\.json$/; // Windows!
|
||||
|
||||
for (i = 0; i < tree.length && found === undefined; ++i) {
|
||||
var tf = tree[i];
|
||||
|
||||
if (re.test(tf) || tf === mf) {
|
||||
found = tf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found === "undefined") {
|
||||
fs.removeDirectoryRecursive(path);
|
||||
throw "Cannot find manifest file in zip file";
|
||||
}
|
||||
|
||||
var mp;
|
||||
|
||||
if (found === mf) {
|
||||
mp = ".";
|
||||
}
|
||||
else {
|
||||
mp = found.substr(0, found.length - mf.length - 1);
|
||||
}
|
||||
|
||||
var manifest = JSON.parse(fs.read(fs.join(path, found)));
|
||||
|
||||
var absolutePath = this.repackZipFile(fs.join(path, mp));
|
||||
|
||||
var result = {
|
||||
name : manifest.name,
|
||||
version: manifest.version,
|
||||
filename: absolutePath.substr(fs.getTempPath().length + 1),
|
||||
configuration: manifest.configuration || {}
|
||||
};
|
||||
|
||||
fs.removeDirectoryRecursive(path);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Inspect a foxx in tmp zip file
|
||||
this.inspect = function (path) {
|
||||
var fullPath = fs.join(fs.getTempPath(), path);
|
||||
try {
|
||||
var result = this.inspectUploadedFile(fullPath);
|
||||
fs.remove(fullPath);
|
||||
return result;
|
||||
} catch (e) {
|
||||
throw new ArangoError();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
|
@ -1,66 +0,0 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief functionality to expose API documentation for Foxx apps
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2013 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
(function() {
|
||||
"use strict";
|
||||
// Get details of one specific installed foxx.
|
||||
exports.Swagger = function (mount) {
|
||||
|
||||
var foxx_manager = require("@arangodb/foxx/manager");
|
||||
|
||||
var result = {},
|
||||
apis = [],
|
||||
pathes,
|
||||
regex = /(:)([^\/]*)/g,
|
||||
i,
|
||||
url,
|
||||
api,
|
||||
ops;
|
||||
var routes = foxx_manager.routes(mount);
|
||||
|
||||
result.swaggerVersion = "1.1";
|
||||
result.basePath = mount;
|
||||
result.apis = apis;
|
||||
result.models = routes.models;
|
||||
pathes = routes.routes;
|
||||
|
||||
for (i in pathes) {
|
||||
if (!pathes[i].internal && pathes[i].url.methods !== undefined) {
|
||||
url = pathes[i].url.match;
|
||||
api = {};
|
||||
ops = [];
|
||||
url = url.replace(regex, "{$2}");
|
||||
api.path = url;
|
||||
ops.push(pathes[i].docs);
|
||||
api.operations = ops;
|
||||
apis.push(api);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}());
|
|
@ -2,11 +2,11 @@
|
|||
"name": "aardvark",
|
||||
"description": "ArangoDB Admin Web Interface",
|
||||
"author": "ArangoDB GmbH",
|
||||
"version": "1.0",
|
||||
"version": "3.0.0",
|
||||
"license": "Apache License, Version 2.0",
|
||||
"isSystem": true,
|
||||
|
||||
"engines": {
|
||||
"arangodb": "^2.8.0"
|
||||
"arangodb": "^3.0.0-0 || ^3.0.0"
|
||||
},
|
||||
|
||||
"repository": {
|
||||
|
@ -29,13 +29,8 @@
|
|||
}
|
||||
],
|
||||
|
||||
"controllers": {
|
||||
"/": "aardvark.js",
|
||||
"/foxxes": "foxxes.js",
|
||||
"/cluster": "cluster.js",
|
||||
"/statistics": "statistics.js",
|
||||
"/templates": "foxxTemplates.js"
|
||||
},
|
||||
"main": "index.js",
|
||||
"defaultDocument": "index.html",
|
||||
|
||||
"files": {
|
||||
"/standalone.html": {
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 100 */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A configuration model for foxx templates
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var Foxx = require("@arangodb/foxx"),
|
||||
joi = require("joi"),
|
||||
Configuration;
|
||||
|
||||
Configuration = Foxx.Model.extend({
|
||||
schema: {
|
||||
applicationContext: joi.string().optional(),
|
||||
path: joi.string().optional(),
|
||||
name: joi.string().required(),
|
||||
collectionNames: joi.array().required(),
|
||||
authenticated: joi.boolean().required(),
|
||||
author: joi.string().required(),
|
||||
description: joi.string().required(),
|
||||
license: joi.string().required()
|
||||
}
|
||||
});
|
||||
|
||||
exports.Model = Configuration;
|
||||
}());
|
|
@ -1,12 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief A TODO-List Foxx-Application written for ArangoDB
|
||||
///
|
||||
/// @file This Document represents the repository communicating with ArangoDB
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
/// Copyright 2010-2013 triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright 2016 ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
|
@ -20,89 +18,71 @@
|
|||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2011-2013, triAGENS GmbH, Cologne, Germany
|
||||
/// @author Alan Plum
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
(function () {
|
||||
"use strict";
|
||||
const db = require('@arangodb').db;
|
||||
const version = String(require('@arangodb/database-version').CURRENT_VERSION);
|
||||
const collection = db._collection('_cluster_kickstarter_plans');
|
||||
|
||||
var _ = require("lodash"),
|
||||
Foxx = require("@arangodb/foxx"),
|
||||
version = require("@arangodb/database-version").CURRENT_VERSION + "", // do not use new String, there is bug in update
|
||||
Plans;
|
||||
module.exports = {
|
||||
hasConfig() {
|
||||
return Boolean(this.loadConfig());
|
||||
},
|
||||
|
||||
Plans = Foxx.Repository.extend({
|
||||
hasConfig: function() {
|
||||
if (this.loadConfig()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
clear() {
|
||||
collection.truncate();
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
this.collection.truncate();
|
||||
},
|
||||
loadConfig() {
|
||||
return collection.any();
|
||||
},
|
||||
|
||||
loadConfig: function() {
|
||||
return this.collection.any();
|
||||
},
|
||||
getPlan() {
|
||||
return this.loadConfig().plan;
|
||||
},
|
||||
|
||||
getPlan: function() {
|
||||
return this.loadConfig().plan;
|
||||
},
|
||||
getRunInfo() {
|
||||
return this.loadConfig().runInfo;
|
||||
},
|
||||
|
||||
getRunInfo: function() {
|
||||
return this.loadConfig().runInfo;
|
||||
},
|
||||
getCredentials() {
|
||||
return this.loadConfig().user;
|
||||
},
|
||||
|
||||
getCredentials: function() {
|
||||
return this.loadConfig().user;
|
||||
},
|
||||
updateConfig(config) {
|
||||
const old = this.loadConfig();
|
||||
collection.update(old._id, config);
|
||||
return true;
|
||||
},
|
||||
|
||||
updateConfig: function(config) {
|
||||
var old = this.loadConfig();
|
||||
this.collection.update(old._id, config);
|
||||
return true;
|
||||
},
|
||||
saveCredentials(name, passwd) {
|
||||
const config = {user: {name, passwd}};
|
||||
const old = this.loadConfig();
|
||||
collection.update(old._id, config);
|
||||
return true;
|
||||
},
|
||||
|
||||
saveCredentials: function(user, passwd) {
|
||||
var config = {
|
||||
user: {
|
||||
name: user,
|
||||
passwd: passwd
|
||||
}
|
||||
};
|
||||
var old = this.loadConfig();
|
||||
this.collection.update(old._id, config);
|
||||
return true;
|
||||
},
|
||||
storeConfig(config) {
|
||||
collection.truncate();
|
||||
config.version = version;
|
||||
collection.save(config);
|
||||
return true;
|
||||
},
|
||||
|
||||
storeConfig: function(config) {
|
||||
this.collection.truncate();
|
||||
config.version = version;
|
||||
this.collection.save(config);
|
||||
return true;
|
||||
},
|
||||
removeRunInfo() {
|
||||
const old = this.loadConfig();
|
||||
delete old.runInfo;
|
||||
collection.replace(old._id, old);
|
||||
return true;
|
||||
},
|
||||
|
||||
removeRunInfo: function() {
|
||||
var old = this.loadConfig();
|
||||
delete old.runInfo;
|
||||
this.collection.replace(old._id, old);
|
||||
return true;
|
||||
},
|
||||
|
||||
replaceRunInfo: function(newInfo) {
|
||||
var old = this.loadConfig();
|
||||
this.collection.update(old._id, {
|
||||
runInfo: newInfo,
|
||||
version: version
|
||||
});
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
exports.Repository = Plans;
|
||||
}());
|
||||
replaceRunInfo(runInfo) {
|
||||
const old = this.loadConfig();
|
||||
collection.update(old._id, {runInfo, version});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue