GUI extension Yeoman generator

Change-Id: If6b3fae44e4ee8a7bde36600cdc71d54d49fbf6e
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/README.md b/generator-xos-gui-extension/generators/templates/conf/app/README.md
new file mode 100755
index 0000000..6c45737
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/README.md
@@ -0,0 +1,45 @@
+# XOS-GUI Config
+
+### Note: The configurations defined in this folder are for development only, they are most likely to be overridden by a volume mount defined in `service-profile`
+
+## App Config
+
+This configuration will specify the REST API base URL and the WebSocket address.
+
+```
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: '/xos/api',
+    websocketClient: '/'
+  });
+
+```
+
+## Style Config
+
+This configuration will contain branding information, such as title, logo and navigation items.
+
+```
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
+```
\ No newline at end of file
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/app.config.dev.js b/generator-xos-gui-extension/generators/templates/conf/app/app.config.dev.js
new file mode 100755
index 0000000..4872661
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/app.config.dev.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: 'http://xos.dev:3000/api',
+    websocketClient: 'http://xos.dev:3000'
+  });
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/app.config.production.js b/generator-xos-gui-extension/generators/templates/conf/app/app.config.production.js
new file mode 100755
index 0000000..de6179f
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/app.config.production.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+angular.module('app')
+  .constant('AppConfig', {
+    apiEndpoint: '/xos/api',
+    websocketClient: '/'
+  });
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/app.config.test.js b/generator-xos-gui-extension/generators/templates/conf/app/app.config.test.js
new file mode 100755
index 0000000..37034fb
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/app.config.test.js
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+angular.module('app')
+  .constant('AppConfig', {
+      apiEndpoint: 'http://xos-test:3000/api',
+      websocketClient: 'http://xos-test:3000'
+  });
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/style.config.cord.js b/generator-xos-gui-extension/generators/templates/conf/app/style.config.cord.js
new file mode 100755
index 0000000..022938b
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/style.config.cord.js
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'CORD',
+    favicon: 'cord-favicon.png',
+    background: 'cord-bg.jpg',
+    payoff: 'Your VNF orchestrator',
+    logo: 'cord-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        },
+        {
+            label: 'Instances',
+            state: 'xos.core.instances'
+        },
+        {
+            label: 'Nodes',
+            state: 'xos.core.nodes'
+        }
+    ]
+});
diff --git a/generator-xos-gui-extension/generators/templates/conf/app/style.config.opencloud.js b/generator-xos-gui-extension/generators/templates/conf/app/style.config.opencloud.js
new file mode 100755
index 0000000..2c1776e
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/app/style.config.opencloud.js
@@ -0,0 +1,32 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+angular.module('app')
+  .constant('StyleConfig', {
+    projectName: 'OpenCloud',
+    favicon: 'opencloud-favicon.png',
+    background: 'opencloud-bg.jpg',
+    payoff: 'Your OS resource manager',
+    logo: 'opencloud-logo.png',
+    routes: [
+        {
+            label: 'Slices',
+            state: 'xos.core.slices'
+        }
+    ]
+});
diff --git a/generator-xos-gui-extension/generators/templates/conf/browsersync-dist.conf.js b/generator-xos-gui-extension/generators/templates/conf/browsersync-dist.conf.js
new file mode 100755
index 0000000..704b46c
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/browsersync-dist.conf.js
@@ -0,0 +1,30 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const conf = require('./gulp.conf');
+
+module.exports = function () {
+  return {
+    server: {
+      baseDir: [
+        conf.paths.dist
+      ]
+    },
+    open: false
+  };
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/browsersync.conf.js b/generator-xos-gui-extension/generators/templates/conf/browsersync.conf.js
new file mode 100755
index 0000000..7e3fbc2
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/browsersync.conf.js
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const conf = require('./gulp.conf');
+const proxy = require('./proxy');
+
+module.exports = function () {
+  return {
+    server: {
+      baseDir: [
+        conf.paths.tmp,
+        conf.paths.src
+      ],
+      middleware: function (req, res, next) {
+        if (req.url.indexOf('xosapi') !== -1 || req.url.indexOf('xos') !== -1 || req.url.indexOf('socket') !== -1) {
+          proxy.api.web(req, res);
+        }
+        else {
+          next();
+        }
+      }
+    },
+    open: false
+  };
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/gulp.conf.js b/generator-xos-gui-extension/generators/templates/conf/gulp.conf.js
new file mode 100755
index 0000000..87b6849
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/gulp.conf.js
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+'use strict';
+
+/**
+ *  This file contains the variables used in other gulp files
+ *  which defines tasks
+ *  By design, we only put there very generic config values
+ *  which are used in several places to keep good readability
+ *  of the tasks
+ */
+
+const path = require('path');
+const gutil = require('gulp-util');
+
+exports.ngModule = 'app';
+
+/**
+ *  The main paths of your project handle these with care
+ */
+exports.paths = {
+  src: 'src',
+  dist: 'dist/extensions/<%= name %>',
+  appConfig: 'conf/app',
+  tmp: '.tmp',
+  e2e: 'e2e',
+  tasks: 'gulp_tasks'
+};
+
+exports.path = {};
+for (const pathName in exports.paths) {
+  if (exports.paths.hasOwnProperty(pathName)) {
+    exports.path[pathName] = function pathJoin() {
+      const pathValue = exports.paths[pathName];
+      const funcArgs = Array.prototype.slice.call(arguments);
+      const joinArgs = [pathValue].concat(funcArgs);
+      return path.join.apply(this, joinArgs);
+    };
+  }
+}
+
+/**
+ *  Common implementation for an error handler of a Gulp plugin
+ */
+exports.errorHandler = function (title) {
+  return function (err) {
+    gutil.log(gutil.colors.red(`[${title}]`), err.toString());
+    this.emit('end');
+  };
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/karma-auto.conf.js b/generator-xos-gui-extension/generators/templates/conf/karma-auto.conf.js
new file mode 100755
index 0000000..f4ce829
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/karma-auto.conf.js
@@ -0,0 +1,79 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const conf = require('./gulp.conf');
+const pkg = require('../package.json');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: false,
+    autoWatch: true,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'PhantomJS',
+      // 'Chrome'
+    ],
+    frameworks: [
+      'jasmine',
+      'es6-shim'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js'),
+      conf.path.src('**/*.html')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ],
+      [conf.path.src('**/*.html')]: [
+        'ng-html2js'
+      ]
+    },
+    ngHtml2JsPreprocessor: {
+      stripPrefix: `${conf.paths.src}/`
+    },
+    reporters: ['mocha', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-phantomjs-launcher'),
+      require('karma-chrome-launcher'),
+      require('karma-phantomjs-shim'),
+      require('karma-ng-html2js-preprocessor'),
+      require('karma-webpack'),
+      require('karma-es6-shim'),
+      require('karma-mocha-reporter')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/karma.conf.js b/generator-xos-gui-extension/generators/templates/conf/karma.conf.js
new file mode 100755
index 0000000..c8bc5f5
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/karma.conf.js
@@ -0,0 +1,75 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const conf = require('./gulp.conf');
+
+module.exports = function (config) {
+  const configuration = {
+    basePath: '../',
+    singleRun: true,
+    autoWatch: false,
+    logLevel: 'INFO',
+    junitReporter: {
+      outputDir: 'test-reports'
+    },
+    browsers: [
+      'PhantomJS'
+    ],
+    frameworks: [
+      'jasmine',
+      'es6-shim'
+    ],
+    files: [
+      'node_modules/es6-shim/es6-shim.js',
+      conf.path.src('index.spec.js'),
+      conf.path.src('**/*.html')
+    ],
+    preprocessors: {
+      [conf.path.src('index.spec.js')]: [
+        'webpack'
+      ],
+      [conf.path.src('**/*.html')]: [
+        'ng-html2js'
+      ]
+    },
+    ngHtml2JsPreprocessor: {
+      stripPrefix: `${conf.paths.src}/`
+    },
+    reporters: ['progress', 'coverage'],
+    coverageReporter: {
+      type: 'html',
+      dir: 'coverage/'
+    },
+    webpack: require('./webpack-test.conf'),
+    webpackMiddleware: {
+      noInfo: true
+    },
+    plugins: [
+      require('karma-jasmine'),
+      require('karma-junit-reporter'),
+      require('karma-coverage'),
+      require('karma-phantomjs-launcher'),
+      require('karma-phantomjs-shim'),
+      require('karma-ng-html2js-preprocessor'),
+      require('karma-webpack'),
+      require('karma-es6-shim')
+    ]
+  };
+
+  config.set(configuration);
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/proxy.js b/generator-xos-gui-extension/generators/templates/conf/proxy.js
new file mode 100644
index 0000000..ab11963
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/proxy.js
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const httpProxy = require('http-proxy');
+
+const target = process.env.PROXY || '192.168.46.100';
+
+const apiProxy = httpProxy.createProxyServer({
+  target: `http://${target}`
+});
+
+apiProxy.on('error', (error, req, res) => {
+  res.writeHead(500, {
+    'Content-Type': 'text/plain'
+  });
+  console.error('[Proxy]', error);
+});
+
+module.exports = {
+  api: apiProxy
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/webpack-dist.conf.js b/generator-xos-gui-extension/generators/templates/conf/webpack-dist.conf.js
new file mode 100755
index 0000000..c870043
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/webpack-dist.conf.js
@@ -0,0 +1,121 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const pkg = require('../package.json');
+const autoprefixer = require('autoprefixer');
+const BaseHrefWebpackPlugin = require('base-href-webpack-plugin').BaseHrefWebpackPlugin;
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
+
+module.exports = {
+  module: {
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: ExtractTextPlugin.extract({
+          fallbackLoader: 'style',
+          loader: 'css?minimize!sass!postcss'
+        })
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+    ]),
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      inject: true,
+      template: conf.path.src('index.html')
+    }),
+    new webpack.optimize.UglifyJsPlugin({
+      compress: {unused: true, dead_code: true, warnings: false}, // eslint-disable-line camelcase
+      mangle: false // NOTE mangling was breaking the build
+    }),
+    new ExtractTextPlugin('index-[contenthash].css'),
+    new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}),
+    new webpack.ProvidePlugin({
+      $: "jquery",
+      jQuery: "jquery"
+    }),
+    new BaseHrefWebpackPlugin({
+      baseHref: '/spa/'
+    }),
+  ],
+  postcss: () => [autoprefixer],
+  output: {
+    path: path.join(process.cwd(), conf.paths.dist),
+    publicPath: "/xos/", // enable apache proxying on the head node
+    filename: '[name].js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  entry: {
+    app: `./${conf.path.src('index')}`,
+    vendor: Object.keys(pkg.dependencies)
+  },
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
+
diff --git a/generator-xos-gui-extension/generators/templates/conf/webpack-test.conf.js b/generator-xos-gui-extension/generators/templates/conf/webpack-test.conf.js
new file mode 100755
index 0000000..c0115ab
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/webpack-test.conf.js
@@ -0,0 +1,84 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: [
+          'style',
+          'css',
+          'sass',
+          'postcss'
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [],
+  debug: true,
+  devtool: 'source-map',
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  }
+};
diff --git a/generator-xos-gui-extension/generators/templates/conf/webpack.conf.js b/generator-xos-gui-extension/generators/templates/conf/webpack.conf.js
new file mode 100755
index 0000000..d70e771
--- /dev/null
+++ b/generator-xos-gui-extension/generators/templates/conf/webpack.conf.js
@@ -0,0 +1,117 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+const webpack = require('webpack');
+const conf = require('./gulp.conf');
+const path = require('path');
+
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const autoprefixer = require('autoprefixer');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const env = process.env.NODE_ENV || 'production';
+const brand = process.env.BRAND || 'cord';
+
+module.exports = {
+  module: {
+    preLoaders: [
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loader: 'tslint'
+      }
+    ],
+
+    loaders: [
+      {
+        test: /.json$/,
+        loaders: [
+          'json'
+        ]
+      },
+      {
+        test: /\.(css|scss)$/,
+        loaders: [
+          'style',
+          'css',
+          'sass',
+          'postcss'
+        ]
+      },
+      {
+        test: /\.ts$/,
+        exclude: /node_modules/,
+        loaders: [
+          'ng-annotate',
+          'ts'
+        ]
+      },
+      {
+        test: /.html$/,
+        loaders: [
+          'html?' + JSON.stringify({
+            attrs: ["img:src", "img:ng-src"]
+          })
+        ]
+      },
+      {
+        test: /\.(png|woff|woff2|eot|ttf|svg|jpg|gif|jpeg)$/,
+        loader: 'url-loader?limit=100000'
+      }
+    ]
+  },
+  plugins: [
+    new CopyWebpackPlugin([
+      { from: `./conf/app/app.config.${env}.js`, to: `app.config.js` },
+      { from: `./conf/app/style.config.${brand}.js`, to: `style.config.js` },
+    ]),
+    new webpack.optimize.OccurrenceOrderPlugin(),
+    new webpack.NoErrorsPlugin(),
+    new HtmlWebpackPlugin({
+      template: conf.path.src('index.html')
+    })
+  ],
+  postcss: () => [autoprefixer],
+  debug: true,
+  devtool: 'source-map',
+  output: {
+    path: path.join(process.cwd(), conf.paths.tmp),
+    filename: 'index.js'
+  },
+  resolve: {
+    extensions: [
+      '',
+      '.webpack.js',
+      '.web.js',
+      '.js',
+      '.ts'
+    ]
+  },
+  entry: `./${conf.path.src('index')}`,
+  ts: {
+    configFileName: 'tsconfig.json'
+  },
+  tslint: {
+    configuration: require('../tslint.json')
+  },
+  stats: {
+    colors: true,
+    modules: true,
+    reasons: true,
+    errorDetails: true
+  }
+};