aboutsummaryrefslogtreecommitdiffstats
path: root/vpp-userdemo/ui/backend
diff options
context:
space:
mode:
authorAristeidis Iliopoulos <ailiopou@cisco.com>2016-09-15 11:36:44 -0700
committerAristeidis Iliopoulos <ailiopou@cisco.com>2016-09-15 18:21:20 -0700
commit417c664ee2bc2a032969639d53b43b732d428e9e (patch)
tree3f17e15f6d0861bb0e35d79771e42e3b7a2d92ea /vpp-userdemo/ui/backend
parent764d4be74089c635598c6f139afc087d1ac55659 (diff)
Added GUI for tutorials that runs entirely inside the VM
-fixed issue with webserver not spinning up properly Change-Id: I3724f1640ba2b84b7d84fab29febbbd047120812 Signed-off-by: Aristeidis Iliopoulos <ailiopou@cisco.com>
Diffstat (limited to 'vpp-userdemo/ui/backend')
-rw-r--r--vpp-userdemo/ui/backend/.bowerrc3
-rw-r--r--vpp-userdemo/ui/backend/bower.json25
-rw-r--r--vpp-userdemo/ui/backend/gulpfile.js173
-rw-r--r--vpp-userdemo/ui/backend/package.json39
-rw-r--r--vpp-userdemo/ui/backend/server.js133
5 files changed, 373 insertions, 0 deletions
diff --git a/vpp-userdemo/ui/backend/.bowerrc b/vpp-userdemo/ui/backend/.bowerrc
new file mode 100644
index 0000000..7fb7ce4
--- /dev/null
+++ b/vpp-userdemo/ui/backend/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "directory": "../frontend/bower_components/"
+} \ No newline at end of file
diff --git a/vpp-userdemo/ui/backend/bower.json b/vpp-userdemo/ui/backend/bower.json
new file mode 100644
index 0000000..204c6dd
--- /dev/null
+++ b/vpp-userdemo/ui/backend/bower.json
@@ -0,0 +1,25 @@
+{
+ "name": "iliogr",
+ "authors": [
+ "Aristeidis Iliopoulos <ailiopou@cisco.com>"
+ ],
+ "description": "scaffold",
+ "main": "",
+ "license": "MIT",
+ "homepage": "",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "bower_components",
+ "test",
+ "tests"
+ ],
+ "dependencies": {
+ "angular": "^1.5.7",
+ "angular-ui-router": "^0.3.1",
+ "angular-material": "^1.0.9",
+ "normalize-css": "^4.2.0",
+ "jquery": "^3.0.0",
+ "ngclipboard": "^1.1.1"
+ }
+}
diff --git a/vpp-userdemo/ui/backend/gulpfile.js b/vpp-userdemo/ui/backend/gulpfile.js
new file mode 100644
index 0000000..5f66cec
--- /dev/null
+++ b/vpp-userdemo/ui/backend/gulpfile.js
@@ -0,0 +1,173 @@
+var gulp = require('gulp');
+var concat = require('gulp-concat');
+var rename = require('gulp-rename');
+var cleanCSS = require('gulp-clean-css');
+var uglify = require('gulp-uglify');
+var mainBowerFiles = require('main-bower-files');
+var gulpFilter = require('gulp-filter');
+var imagemin = require('gulp-imagemin');
+var flatten = require('gulp-flatten');
+var jshint = require('gulp-jshint');
+var sass = require('gulp-sass');
+var watch = require('gulp-watch');
+var wiredep = require('wiredep').stream;
+var series = require('stream-series');
+var inject = require('gulp-inject');
+var clean = require('gulp-clean');
+var livereload = require('gulp-livereload');
+
+var paths = {
+ source: {
+ bower: '../frontend/bower_components',
+ images: '../frontend/assets/images/**',
+ js: '../frontend/**/*.js',
+ html: '../frontend/**/*.html',
+ index: '../frontend/index.html',
+ sass: '../frontend/assets/sass/*.scss',
+ fonts: '../frontend/assets/fonts/**'
+ },
+ target: {
+ dev: '../dist.dev',
+ prod: '../dist.prod',
+ imagesDev: '../dist.dev/images',
+ imagesProd: '../dist.prod/images',
+ htmlDev: '../dist.dev/html',
+ htmlProd: '../dist.prod/html',
+ cssDev: '../dist.dev/css',
+ cssProd: '../dist.prod/cssProd',
+ jsDev: '../dist.dev/js',
+ jsProd: '../dist.prod/js',
+ vendorDev: '../dist.dev/vendor',
+ vendorProd: '../dist.prod/vendor',
+ indexDev: '../dist.dev/html/index.html',
+ indexProd: '../dist.prod/html/index.html',
+ fontsDev: '../dist.dev/fonts',
+ fontsProd: '../dist.prod/fonts'
+ }
+}
+
+gulp.task('bower', function() {
+
+ var jsFilter = gulpFilter(paths.source.bower+'/**/*.js', {restore: true})
+ var cssFilter = gulpFilter(paths.source.bower+'/**/*.css', {restore: true})
+
+ return gulp.src(mainBowerFiles())
+ .pipe(jsFilter)
+ .pipe(concat('vendor.js'))
+ .pipe(gulp.dest(paths.target.vendorDev))
+ .pipe(rename('vendor.min.js'))
+ .pipe(gulp.dest(paths.target.vendorProd))
+ .pipe(jsFilter.restore)
+ .pipe(cssFilter)
+ .pipe(concat('vendor.css'))
+ .pipe(gulp.dest(paths.target.vendorDev))
+ .pipe(rename('vendor.min.css'))
+ .pipe(cleanCSS())
+ .pipe(gulp.dest(paths.target.vendorProd))
+ .pipe(cssFilter.restore)
+ .pipe(livereload());
+});
+
+
+gulp.task('images', function() {
+ return gulp.src(paths.source.images)
+ .pipe(imagemin({ progressive: true }))
+ .pipe(flatten())
+ .pipe(gulp.dest(paths.target.imagesDev))
+ .pipe(gulp.dest(paths.target.imagesProd))
+ .pipe(livereload());
+});
+
+gulp.task('lint', function() {
+ return gulp.src(['!'+paths.source.bower+'/**', paths.source.js])
+ .pipe(jshint())
+ .pipe(jshint.reporter('default'));
+});
+
+gulp.task('html', function() {
+ return gulp.src(['!'+paths.source.bower+'/**', '!'+paths.source.index, paths.source.html])
+ .pipe(flatten())
+ .pipe(gulp.dest(paths.target.htmlDev))
+ .pipe(gulp.dest(paths.target.htmlProd))
+ .pipe(livereload());
+});
+
+gulp.task('fonts', function() {
+ return gulp.src([paths.source.fonts])
+ .pipe(flatten())
+ .pipe(gulp.dest(paths.target.fontsDev))
+ .pipe(gulp.dest(paths.target.fontsProd));
+});
+
+gulp.task('js', function() {
+ return gulp.src(['!'+paths.source.bower+'/**', paths.source.js])
+ .pipe(concat('app.js'))
+ .pipe(gulp.dest(paths.target.jsDev))
+ .pipe(rename('app.min.js'))
+ .pipe(gulp.dest(paths.target.jsProd))
+ .pipe(livereload());
+});
+
+gulp.task('sass', function() {
+ return gulp.src(paths.source.sass)
+ .pipe(sass()).on('error', onError)
+ .pipe(gulp.dest(paths.target.cssDev))
+ .pipe(gulp.dest(paths.target.cssProd))
+ .pipe(livereload());
+});
+
+gulp.task('watch', function() {
+ livereload.listen();
+ gulp.watch([paths.source.images], ['images']);
+ gulp.watch([paths.source.html], ['html']);
+ gulp.watch([paths.source.bower], ['bower']);
+ gulp.watch(['!'+paths.source.bower+'/**', paths.source.js], ['lint', 'js']);
+ gulp.watch(paths.source.sass, ['sass']);
+});
+
+gulp.task('clean', function() {
+ gulp.src(paths.target.dev, {read: false})
+ .pipe(clean({force: true}))
+ gulp.src(paths.target.prod, {read: false})
+ .pipe(clean({force: true}))
+});
+
+gulp.task('injectDev', ['bower', 'sass', 'js'], function () {
+ var target = gulp.src(paths.source.index);
+ var sources = gulp.src([paths.target.vendorDev+'/*.js', paths.target.vendorDev+'/*.css', paths.target.cssDev+'/*.css', paths.target.jsDev+'/*.js'], {read: false});
+ return target.pipe(inject(sources, {addRootSlash : false,
+ transform : function(filePath, file, i, length){
+ var newPath = filePath.replace('dist.dev/', '');
+ if(filePath.match(/.css/)){
+ return '<link rel="stylesheet" href="'+newPath+'">'
+ }
+ else
+ return '<script src="'+newPath+'"></script>';
+ }}))
+ .pipe(gulp.dest(paths.target.htmlDev));
+});
+
+gulp.task('injectProd', ['bower', 'sass', 'js'], function () {
+ var target = gulp.src(paths.source.index);
+ var sources = gulp.src([paths.target.vendorProd+'/*.js', paths.target.vendorProd+'/*.css', paths.target.cssProd+'/*.css', paths.target.jsProd+'/*.js'], {read: false});
+ return target.pipe(inject(sources, {addRootSlash : false,
+ transform : function(filePath, file, i, length){
+ var newPath = filePath.replace('dist.prod/', '');
+ if(filePath.match(/.css/)){
+ return '<link rel="stylesheet" href="'+newPath+'">'
+ }
+ else
+ return '<script src="'+newPath+'"></script>';
+ }}))
+ .pipe(gulp.dest(paths.target.htmlProd));
+});
+
+function onError(err) {
+ console.log(err);
+ this.emit('end');
+}
+
+gulp.task('default', ['bower', 'lint', 'js', 'sass', 'images', 'fonts', 'html', 'injectDev', 'injectProd', 'watch']);
+
+
+
diff --git a/vpp-userdemo/ui/backend/package.json b/vpp-userdemo/ui/backend/package.json
new file mode 100644
index 0000000..1aedcab
--- /dev/null
+++ b/vpp-userdemo/ui/backend/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "vppsb",
+ "version": "1.0.0",
+ "description": "",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "Aris Iliopoulos",
+ "license": "ISC",
+ "dependencies": {
+ "body-parser": "^1.15.1",
+ "express": "^4.13.4",
+ "ip": "^1.1.3",
+ "ssh2": "^0.5.1",
+ "untildify": "^3.0.2",
+ "winston": "^2.2.0"
+ },
+ "devDependencies": {
+ "gulp": "^3.9.1",
+ "gulp-clean": "^0.3.2",
+ "gulp-clean-css": "^2.0.10",
+ "gulp-concat": "^2.6.0",
+ "gulp-filter": "^4.0.0",
+ "gulp-flatten": "^0.3.0",
+ "gulp-imagemin": "^3.0.1",
+ "gulp-jshint": "^2.0.1",
+ "gulp-livereload": "^3.8.1",
+ "gulp-rename": "^1.2.2",
+ "gulp-sass": "^2.3.2",
+ "gulp-inject": "^4.1.0",
+ "gulp-uglify": "^1.5.4",
+ "gulp-watch": "^4.3.8",
+ "jshint": "^2.9.2",
+ "main-bower-files": "^2.13.1",
+ "stream-series": "^0.1.1",
+ "wiredep": "^4.0.0"
+ }
+}
diff --git a/vpp-userdemo/ui/backend/server.js b/vpp-userdemo/ui/backend/server.js
new file mode 100644
index 0000000..3523708
--- /dev/null
+++ b/vpp-userdemo/ui/backend/server.js
@@ -0,0 +1,133 @@
+// =========================================================================
+// ==================== get the packages we need ===========================
+// =========================================================================
+var express = require('express');
+var app = express();
+var v1 = new express.Router();
+var bodyParser = require('body-parser');
+var ip = require('ip');
+var fs = require('fs');
+var path = require('path');
+var fs = require('fs');
+var untildify = require('untildify');
+var Client = require('ssh2').Client;
+var conn = new Client();
+var PATH = untildify('~/');
+var winston = require('winston');
+var exec = require('child_process').exec;
+// ===========================================================================
+// ================== Initialize the logging system ==========================
+// ===========================================================================
+var logger = new (winston.Logger)({
+ transports: [
+ new (winston.transports.File)({
+ name: 'info-file',
+ filename: 'node-info.log',
+ level: 'info'
+ }),
+ new (winston.transports.File)({
+ name: 'error-file',
+ filename: 'node-error.log',
+ level: 'error'
+ })
+ ]
+});
+// ==========================================================================
+// ====================== start the webserver ==============================
+// ==========================================================================
+var server = app.listen(5000, ip.address(), function() {
+ console.log('Server running at http://'+ip.address()+':'+5000);
+ logger.log('info', 'Server running at http://'+ip.address()+':'+5000);
+});
+// ===========================================================================
+// ================ Initialize express dependencies ==========================
+// ===========================================================================
+app.use(bodyParser.urlencoded({extended: false}));
+app.use(bodyParser.json());
+app.use(express.static(__dirname + '/../dist.prod'));
+// Removing Angular's annoying # from the URL
+app.get('/', function(req, res) {
+ res.sendFile(path.join(__dirname + '/../dist.prod/html/index.html'));
+});
+// ===========================================================================
+// ================= Initialize the API routes ===============================
+// ===========================================================================
+app.use('/api/v1', v1);
+
+var TUTORIALS_PATH = __dirname+'/../../tutorials';
+var CMDS_REGEXP = /CMD\+=\("(.*)"\)/gmi;
+var INSTR_REGEXP = /INSTR\+=\("(.*)"\)/gmi;
+var C1_IP_REGEXP = /C1_IP="(.*)"/gmi;
+var C1_GW_REGEXP = /C1_GW="(.*)"/gmi;
+var C2_IP_REGEXP = /C2_IP="(.*)"/gmi;
+var C2_GW_REGEXP = /C2_GW="(.*)"/gmi;
+
+
+function grabTutorials(req, res, next){
+
+ var TUTORIALS = [];
+ fs.readdir(TUTORIALS_PATH, function(err, data) {
+ if (err) {
+ return console.log(err);
+ }
+else
+ for(var x = 0; x < data.length; x++){
+ if(data[x].match(/^[^.]+$|.*\.sh/g)){
+ TUTORIALS.push(data[x]);
+ }
+ }
+ logger.log('info', 'Tutorials are sent to the client');
+ res.send(TUTORIALS);
+ });
+}
+
+function grabFile(req, res, next){
+
+ fs.readFile(TUTORIALS_PATH+'/'+req.params.tutorial, 'utf8', function (err,data) {
+ if (err) {
+ return console.log(err);
+ }
+ var CMD = '';
+ var commands = [];
+ var INSTR = '';
+ var instructions = [];
+ var IP1 = '';
+ var IP2 = '';
+ var GW1 = '';
+ var GW2 = '';
+
+ CMD = data.match(CMDS_REGEXP);
+ INSTR = data.match(INSTR_REGEXP);
+ IP1 = data.match(C1_IP_REGEXP);
+ IP2 = data.match(C2_IP_REGEXP);
+ GW1 = data.match(C1_GW_REGEXP);
+ GW2 = data.match(C2_GW_REGEXP);
+
+ IP1 = IP1[0].replace('C1_IP="', "").replace('"', "");
+ IP2 = IP2[0].replace('C2_IP="', "").replace('"', "");
+ GW1 = GW1[0].replace('C1_GW="', "").replace('"', "");
+ GW2 = GW2[0].replace('C2_GW="', "").replace('"', "");
+
+ for(var x = 0; x < INSTR.length; x++){
+ commands.push(CMD[x].replace('CMD+=("', "").replace('")', ""));
+ instructions.push(INSTR[x].replace('INSTR+=("', "").replace('")', ""));
+ }
+ exec('/vagrant/netns.sh '+IP1+' '+GW1+' '+IP2+' '+GW2, function(error, stdout, stderr) {
+ res.send({commands: commands, instructions: instructions});
+ });
+ });
+}
+
+function runCommand(req, res, next){
+ //Removing the out of bounds error
+ if(req.body.command == ''){req.body.command = ' '}
+ exec(req.body.command, function(error, stdout, stderr) {
+ if(stderr){res.send(stderr)}
+ else if(stdout){res.send(stdout)}
+ else{res.send(error)}
+ });
+}
+
+v1.get('/tutorials', grabTutorials);
+v1.get('/file/:tutorial', grabFile);
+v1.post('/command', runCommand);