/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
render() {
let self = this;
let {children, className, title, ...props} = self.props;
- let classRoot = className ? ' ' + className : ' '
+ let classRoot = className ? ' ' + className : ' ';
+ let hasCorners = this.props['no-corners'];
let titleTag = title ? <header className="skyquakePanel-title">{title}</header> : '';
return (
<section className={'skyquakePanel' + classRoot} style={props.style}>
- <i className="corner-accent top left"></i>
- <i className="corner-accent top right"></i>
+ { !hasCorners ? <i className="corner-accent top left"></i> : null }
+ { !hasCorners ? <i className="corner-accent top right"></i> : null }
{titleTag}
<div className="skyquakePanel-wrapper">
<div className={(classRoot ? 'skyquakePanel-body ' + decorateClassNames(classRoot, '-body') : 'skyquakePanel-body')}>
{children}
</div>
</div>
- <i className="corner-accent bottom left"></i>
- <i className="corner-accent bottom right"></i>
+ { !hasCorners ? <i className="corner-accent bottom left"></i> : null }
+ { !hasCorners ? <i className="corner-accent bottom right"></i> : null }
</section>
)
}
export class PanelWrapper extends Component {
render() {
- return (<div className={'skyquakePanelWrapper'}>
+ return (
+ <div className={'skyquakePanelWrapper ' + this.props.className} style={this.props.style}>
{this.props.children}
</div>)
}
function decorateClassNames(className, addendum) {
- return className.split(' ').map(function(c) {
+ return className.trim().split(' ').map(function(c) {
return c + addendum
}).join(' ');
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
}
}
+.skyquakePanelWrapper.column {
+ .skyquakePanel-wrapper {
+ height:auto;
+ }
+}
+
/* Style for storybook */
body{
height:100%;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
}
render() {
- const {displayNotification, notificationMessage, displayScreenLoader, ...state} = this.state;
+ const {displayNotification, notificationMessage, displayScreenLoader, notificationType, ...state} = this.state;
var html;
if (this.matchesLoginUrl()) {
<Crouton
id={Date.now()}
message={notificationMessage}
- type={"error"}
+ type={notificationType}
hidden={!(displayNotification && notificationMessage)}
onDismiss={SkyquakeContainerActions.hideNotification}
/>
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
//Notification defaults
this.notificationMessage = '';
this.displayNotification = false;
+ this.notificationType = 'error';
//Screen Loader default
this.displayScreenLoader = false;
this.bindActions(SkyquakeContainerActions);
let connection = data.connection;
let streamSource = data.streamSource;
console.log('Success opening notification socket for stream ', streamSource);
-
+
let ws = window.multiplexer.channel(connection);
-
+
if (!connection) return;
self.setState({
socket: ws.ws,
//Notifications
showNotification = (data) => {
- if(typeof(data) == 'string') {
- this.setState({
+ let state = {
displayNotification: true,
- notificationMessage: data
- });
+ notificationMessage: data,
+ notificationType: 'error',
+ displayScreenLoader: false
+ }
+ if(typeof(data) == 'string') {
+
} else {
- if(data.type == 'error') {
- this.setState({
- displayNotification: true,
- notificationMessage: data.msg,
- displayScreenLoader: false
- });
+ state.notificationMessage = data.msg;
+ if(data.type == 'success') {
+ state.notificationType = 'success';
}
}
+ this.setState(state);
}
hideNotification = () => {
this.setState({
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
utils.sendErrorResponse(error, res);
});
})
-
+ utils.passThroughConstructor(app);
module.exports = app;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
'deleteAccountSuccess',
'deleteAccountLoading',
'deleteAccountFail',
- 'viewAccount'
+ 'viewAccount',
+ 'getResourceOrchestratorSuccess'
);
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
success: Alt.actions.global.deleteAccountSuccess,
loading: Alt.actions.global.deleteAccountLoading,
error: Alt.actions.global.showNotification
- }
+ },
+ getResourceOrchestrator: {
+ remote: function() {
+ return new Promise(function(resolve, reject) {
+ $.ajax({
+ url: 'passthrough/data/api/running/resource-orchestrator' + '?api_server=' + API_SERVER,
+ type: 'GET',
+ beforeSend: Utils.addAuthorizationStub,
+ contentType: "application/json",
+ success: function(data) {
+ resolve(data["rw-launchpad:resource-orchestrator"]);
+ },
+ error: function(error) {
+ console.log("There was an error updating the account: ", arguments);
+
+ }
+ }).fail(function(xhr){
+ //Authentication and the handling of fail states should be wrapped up into a connection class.
+ Utils.checkAuthentication(xhr.status);
+ return reject('error');
+ });
+ });
+ },
+ interceptResponse: interceptResponse({
+ 'error': 'There was an error retrieving the resource orchestrator information.'
+ }),
+ success: Alt.actions.global.getResourceOrchestratorSuccess,
+ loading: Alt.actions.global.showScreenLoader,
+ error: Alt.actions.global.showNotification
+ },
}
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
ref: 'floating-ip-pool',
optional: true
}],
- "openmano": [{
- label: "Host",
- ref: 'host'
- }, {
- label: "Port",
- ref: 'port'
- }, {
- label: "Tenant ID",
- ref: 'tenant-id'
- }],
"openvim": [{
label: "Host",
ref: 'host'
}, {
"name": "Cloudsim",
"account-type": "cloudsim_proxy"
- }, {
- "name": "Open Mano",
- "account-type": "openmano"
}, {
"name": "AWS",
"account-type": "aws"
},
image: {
"aws": require("../../images/aws.png"),
- "openmano": altImage || require("../../images/openmano.png"),
"openvim": require("../../images/openmano.png"),
"openstack": require("../../images/openstack.png"),
"cloudsim_proxy": require("../../images/riftio.png"),
},
labelByType: {
"aws": "AWS",
- "openmano": "OpenStack",
"openvim": "Open VIM",
"openstack": "OpenStack",
"cloudsim_proxy": "Cloudsim"
this.refreshingAll = false;
this.sdnOptions = [];
this.AccountMeta = AccountMeta;
+ this.showVIM = true;
this.bindActions(AccountActions(this.alt));
this.registerAsync(AccountSource);
this.exportPublicMethods({
}
refreshCloudAccountSuccess = () => {
+ }
+ getResourceOrchestratorSuccess = (data) => {
+ this.alt.actions.global.hideScreenLoader.defer();
+ if(data['account-type'] == 'openmano') {
+ this.setState({
+ showVIM: false
+ })
+ }
}
deleteAccountSuccess = (response) => {
this.setState({
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
componentWillMount() {
this.Store.listen(this.updateState);
this.Store.openAccountsSocket();
+ this.Store.getResourceOrchestrator();
}
componentWillUnmount() {
this.Store.closeSocket();
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
html = (
<div className='accountSidebar'>
<Button className="refreshList light" onClick={this.props.store.refreshAll.bind(this, AccountData)} label={this.props.refreshingAll ? 'Checking Connectivity Status...' : refreshStatus}></Button>
- <h1>VIM Accounts</h1>
- {cloudAccounts}
- <DashboardCard className="accountSidebarCard">
- <Link
- to={{pathname: '/accounts/cloud/create'}}
- title="Create Cloud Account"
- className={'accountSidebarCard_create'}
- >
- Add VIM Account
- <img src={require("style/img/launchpad-add-fleet-icon.png")}/>
- </Link>
- </DashboardCard>
+ {props.showVIM ? (
+ <div>
+ <h1>VIM Accounts</h1>
+ {cloudAccounts}
+ <DashboardCard className="accountSidebarCard">
+ <Link
+ to={{pathname: '/accounts/cloud/create'}}
+ title="Create Cloud Account"
+ className={'accountSidebarCard_create'}
+ >
+ Add VIM Account
+ <img src={require("style/img/launchpad-add-fleet-icon.png")}/>
+ </Link>
+ </DashboardCard>
+ </div>)
+ : null}
<h1>SDN Accounts</h1>
{sdnAccounts}
<DashboardCard className="accountSidebarCard">
--- /dev/null
+# RIFT_IO_STANDARD_CMAKE_COPYRIGHT_HEADER(BEGIN)
+# Author(s): Kiran Kashalkar
+# Creation Date: 08/18/2015
+# RIFT_IO_STANDARD_CMAKE_COPYRIGHT_HEADER(END)
+
+##
+# DEPENDENCY ALERT
+# The submodule dependencies must be specified in the
+# .gitmodules.dep file at the top level (supermodule) directory
+# If this submodule depends other submodules remember to update
+# the .gitmodules.dep
+##
+
+cmake_minimum_required(VERSION 2.8)
+
+##
+# Submodule specific includes will go here,
+# These are specified here, since these variables are accessed
+# from multiple sub directories. If the variable is subdirectory
+# specific it must be declared in the subdirectory.
+##
+
+rift_externalproject_add(
+ config
+ SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}
+ CONFIGURE_COMMAND echo
+ BUILD_COMMAND
+ ${CMAKE_CURRENT_BINARY_DIR}/config/config-build/scripts/build.sh
+ INSTALL_COMMAND
+ ${CMAKE_CURRENT_SOURCE_DIR}/scripts/install.sh
+ ${CMAKE_CURRENT_BINARY_DIR}/config/config-build
+ ${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+ ${RIFT_SUBMODULE_INSTALL_PREFIX}/skyquake/${CMAKE_INSTALL_PREFIX}/usr/share/rw.ui/skyquake
+
+ BCACHE_COMMAND echo
+)
+
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+
+var request = require('request');
+var Promise = require('bluebird');
+var rp = require('request-promise');
+var utils = require('../../../framework/core/api_utils/utils.js');
+var constants = require('../../../framework/core/api_utils/constants.js');
+var _ = require('underscore');
+var RO = {}
+RO.get = function(req) {
+return new Promise(function(resolve, reject) {
+ var self = this;
+ var api_server = req.query["api_server"];
+ var requestHeaders = {};
+ var url = utils.confdPort(api_server) + '/api/running/resource-orchestrator';
+ _.extend(
+ requestHeaders,
+ id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
+ 'Authorization': req.get('Authorization')
+ }
+ );
+
+ request({
+ url: url + '?deep',
+ type: 'GET',
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false
+ },
+ function(error, response, body) {
+ var data;
+ if (utils.validateResponse('RO.get', error, response, body, resolve, reject)) {
+ try {
+ data = JSON.parse(response.body);
+ if (!id) {
+ data = data.collection;
+ }
+
+ data = data[objKey]
+ } catch (e) {
+ console.log('Problem with "' + type.toUpperCase() + '.get"', e);
+ var err = {};
+ err.statusCode = 500;
+ err.errorMessage = {
+ error: 'Problem with "' + type.toUpperCase() + '.get": ' + e
+ }
+ return reject(err);
+ }
+ return resolve({
+ statusCode: response.statusCode,
+ data: data
+ });
+ };
+ });
+ });
+}
+
+RO.update = updateAccount;
+
+function updateAccount(req) {
+ var self = this;
+ var api_server = req.query["api_server"];
+ var data = req.body;
+ var requestHeaders = {};
+ var url = utils.confdPort(api_server) + '/api/config/resource-orchestrator';
+ var method = 'PUT'
+
+ return new Promise(function(resolve, reject) {
+ _.extend(requestHeaders,
+ constants.HTTP_HEADERS.accept.data,
+ constants.HTTP_HEADERS.content_type.data, {
+ 'Authorization': req.get('Authorization')
+ });
+ request({
+ url: url,
+ method: method,
+ headers: requestHeaders,
+ forever: constants.FOREVER_ON,
+ rejectUnauthorized: false,
+ json: data,
+ }, function(error, response, body) {
+ if (utils.validateResponse('RO.update', error, response, body, resolve, reject)) {
+ return resolve({
+ statusCode: response.statusCode,
+ data: JSON.stringify(response.body)
+ });
+ };
+ });
+ })
+}
+
+module.exports = RO;
--- /dev/null
+{
+ "root": "public",
+ "name": "Config",
+ "dashboard": "./dashboard/dashboard.jsx",
+ "order": 1,
+ "priority":1,
+ "routes": [
+ {
+ "label": "Configuration Dashboard",
+ "route": "accounts",
+ "component": "./dashboard/dashboard.jsx",
+ "path": "accounts",
+ "type": "internal"
+ }]
+}
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="1190.55px" height="841.89px" viewBox="0 0 1190.55 841.89" enable-background="new 0 0 1190.55 841.89"
+ xml:space="preserve">
+<g>
+ <g>
+ <path fill="#DD4814" d="M657.621,123.565c-73.488,0-133.063,59.573-133.063,133.062s59.576,133.069,133.063,133.069
+ c73.49,0,133.064-59.58,133.064-133.069S731.111,123.565,657.621,123.565z"/>
+ <path fill="#FFFFFF" d="M593.043,338.909c-1.128,1.128-2.632,1.75-4.233,1.75l0,0c-1.605,0-3.112-0.624-4.244-1.757
+ c-1.129-1.128-1.751-2.632-1.751-4.234c0-1.602,0.622-3.105,1.751-4.235c1.133-1.132,2.64-1.756,4.243-1.756
+ c1.601,0,3.104,0.622,4.233,1.751c1.131,1.131,1.753,2.637,1.753,4.24C594.797,336.273,594.174,337.779,593.043,338.909z"/>
+ <path fill="#FFFFFF" d="M619.154,249.424c-0.603-1.92-1.47-3.498-2.579-4.69c-1.105-1.193-2.443-2.085-3.978-2.653
+ c-1.543-0.574-3.291-0.865-5.194-0.865s-3.636,0.29-5.147,0.863c-1.509,0.569-2.834,1.462-3.939,2.654
+ c-1.107,1.19-1.974,2.769-2.578,4.691c-0.606,1.933-0.914,4.299-0.914,7.032v69.735h-12.038V255.39
+ c0-3.572,0.484-6.896,1.438-9.88c0.957-2.996,2.463-5.641,4.475-7.863c2.015-2.226,4.586-3.976,7.643-5.203
+ c3.05-1.226,6.742-1.848,10.973-1.848c4.229,0,7.949,0.622,11.059,1.847c3.115,1.227,5.717,2.978,7.732,5.204
+ c2.01,2.219,3.532,4.863,4.52,7.861c0.985,2.985,1.485,6.311,1.485,9.882V265h-12.038v-8.544
+ C620.072,253.733,619.763,251.367,619.154,249.424z"/>
+ <path fill="#FFFFFF" d="M669.396,298.309c0,3.579-0.499,6.905-1.483,9.885c-0.985,2.99-2.507,5.634-4.521,7.86
+ c-2.016,2.225-4.617,3.976-7.732,5.203c-3.112,1.226-6.833,1.848-11.06,1.848s-7.917-0.622-10.972-1.849
+ c-3.055-1.226-5.626-2.976-7.642-5.201c-2.014-2.226-3.52-4.872-4.476-7.864c-0.954-2.983-1.437-6.308-1.437-9.882v-30.425h12.037
+ v29.361c0,2.734,0.309,5.099,0.914,7.029c0.603,1.924,1.471,3.502,2.578,4.694c1.106,1.194,2.434,2.087,3.938,2.654
+ c1.511,0.573,3.242,0.863,5.147,0.863c1.903,0,3.651-0.291,5.193-0.864c1.533-0.568,2.871-1.461,3.979-2.653
+ c1.108-1.194,1.979-2.773,2.579-4.693c0.607-1.94,0.917-4.305,0.917-7.03v-29.361h12.038V298.309z"/>
+ <path fill="#FFFFFF" d="M657.387,259.099c0-3.302,2.685-5.989,5.986-5.989c3.305,0,5.995,2.687,5.995,5.989
+ c0,3.305-2.69,5.994-5.995,5.994C660.071,265.093,657.387,262.404,657.387,259.099z"/>
+ <path fill="#FFFFFF" d="M693.726,174.163c-0.603-1.92-1.472-3.499-2.581-4.693c-1.107-1.193-2.446-2.085-3.979-2.652
+ c-1.54-0.573-3.288-0.863-5.193-0.863c-1.903,0-3.635,0.29-5.146,0.862c-1.508,0.569-2.834,1.462-3.941,2.653
+ c-1.105,1.193-1.973,2.772-2.575,4.693c-0.606,1.932-0.914,4.298-0.914,7.032v69.734h-12.038v-70.8
+ c0-3.571,0.482-6.896,1.438-9.881c0.958-2.996,2.463-5.642,4.477-7.863c2.012-2.224,4.584-3.975,7.643-5.202
+ c3.055-1.227,6.744-1.849,10.969-1.849c4.227,0,7.948,0.622,11.06,1.848c3.119,1.228,5.719,2.979,7.731,5.203
+ c2.014,2.22,3.535,4.865,4.522,7.86c0.983,2.988,1.483,6.314,1.483,9.885v9.609h-12.04v-8.543
+ C694.64,178.467,694.332,176.101,693.726,174.163z"/>
+ <path fill="#FFFFFF" d="M743.963,223.048c0,3.577-0.499,6.903-1.482,9.884c-0.986,2.993-2.506,5.638-4.518,7.86
+ c-2.018,2.226-4.619,3.976-7.732,5.203c-3.115,1.226-6.837,1.848-11.06,1.848c-4.229,0-7.921-0.622-10.974-1.849
+ c-3.057-1.226-5.626-2.976-7.642-5.201c-2.012-2.223-3.518-4.868-4.476-7.863c-0.954-2.989-1.438-6.313-1.438-9.881v-30.426
+ h12.038v29.361c0,2.729,0.308,5.095,0.915,7.031c0.603,1.92,1.469,3.499,2.58,4.692c1.106,1.194,2.432,2.087,3.937,2.654
+ c1.513,0.573,3.243,0.863,5.146,0.863c1.907,0,3.654-0.291,5.194-0.864c1.534-0.566,2.872-1.459,3.981-2.653
+ c1.106-1.19,1.975-2.769,2.577-4.692c0.607-1.936,0.916-4.301,0.916-7.031v-29.361h12.037V223.048z"/>
+ </g>
+ <g>
+ <path d="M360.49,646.299c-2.566,0-5.878-0.32-9.943-0.962c-4.06-0.642-7.482-1.498-10.264-2.565l3.849-24.377
+ c2.14,0.641,4.601,1.172,7.377,1.603c2.781,0.427,5.347,0.642,7.698,0.642c10.265,0,17.586-3.157,21.972-9.461
+ c4.38-6.311,6.575-15.557,6.575-27.746V419.527h29.83v163.584c0,21.38-4.866,37.257-14.594,47.631
+ C393.257,641.112,379.094,646.299,360.49,646.299z"/>
+ <path d="M595.598,581.507c-6.847,1.714-15.877,3.528-27.103,5.454c-11.227,1.924-24.217,2.887-38.972,2.887
+ c-12.83,0-23.63-1.875-32.396-5.614c-8.771-3.738-15.826-9.03-21.168-15.876c-5.348-6.842-9.197-14.916-11.547-24.218
+ c-2.356-9.302-3.528-19.616-3.528-30.952v-93.66h29.83v87.245c0,20.317,3.208,34.856,9.622,43.622
+ c6.416,8.771,17.21,13.15,32.396,13.15c3.208,0,6.52-0.105,9.943-0.32c3.417-0.211,6.625-0.481,9.623-0.802
+ c2.992-0.321,5.718-0.642,8.179-0.963c2.457-0.32,4.22-0.691,5.293-1.122V419.527h29.83V581.507z"/>
+ <path d="M615.162,646.299c-2.566,0-5.879-0.32-9.943-0.962c-4.06-0.642-7.484-1.498-10.265-2.565l3.85-24.377
+ c2.14,0.641,4.601,1.172,7.377,1.603c2.782,0.427,5.348,0.642,7.698,0.642c10.265,0,17.587-3.157,21.972-9.461
+ c4.38-6.311,6.575-15.557,6.575-27.746V419.527h29.83v163.584c0,21.38-4.866,37.257-14.595,47.631
+ C647.929,641.112,633.766,646.299,615.162,646.299z"/>
+ <path d="M850.27,581.507c-6.846,1.714-15.878,3.528-27.104,5.454c-11.227,1.924-24.217,2.887-38.972,2.887
+ c-12.83,0-23.63-1.875-32.396-5.614c-8.771-3.738-15.827-9.03-21.17-15.876c-5.347-6.842-9.196-14.916-11.547-24.218
+ c-2.355-9.302-3.528-19.616-3.528-30.952v-93.66h29.83v87.245c0,20.317,3.207,34.856,9.622,43.622
+ c6.415,8.771,17.211,13.15,32.396,13.15c3.207,0,6.521-0.105,9.942-0.32c3.419-0.211,6.627-0.481,9.624-0.802
+ c2.991-0.321,5.718-0.642,8.179-0.963c2.455-0.32,4.22-0.691,5.292-1.122V419.527h29.83V581.507z"/>
+ </g>
+</g>
+</svg>
--- /dev/null
+{
+ "name": "config",
+ "version": "1.0.0",
+ "description": "",
+ "main": "routes.js",
+ "scripts": {
+ "start": "rm -rf public/ && mkdir public && cd public && mkdir build && cp ../src/index.html ./ && node ../server.js"
+ },
+ "author": "RIFT.io",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "alt": "^0.18.3",
+ "bluebird": "^3.4.1",
+ "express": "^4.13.3",
+ "history": "^1.17.0",
+ "jquery": "^2.2.1",
+ "json-loader": "^0.5.4",
+ "lodash": "^4.10.0",
+ "normalizr": "^2.1.0",
+ "open-iconic": "^1.1.1",
+ "prismjs": "^1.4.1",
+ "react": "^0.14.8",
+ "react-breadcrumbs": "^1.3.9",
+ "react-crouton": "^0.2.7",
+ "react-dom": "^0.14.6",
+ "react-router": "^2.0.1",
+ "react-slick": "^0.11.1",
+ "react-tabs": "^0.5.3",
+ "react-treeview": "^0.4.2",
+ "request-promise": "^3.0.0",
+ "underscore": "^1.8.3"
+ },
+ "devDependencies": {
+ "babel-core": "^6.4.5",
+ "babel-loader": "^6.2.1",
+ "babel-polyfill": "^6.9.1",
+ "babel-preset-es2015": "^6.6.0",
+ "babel-preset-react": "^6.5.0",
+ "babel-preset-stage-0": "^6.3.13",
+ "babel-runtime": "^6.3.19",
+ "cors": "^2.7.1",
+ "css-loader": "^0.23.1",
+ "file-loader": "^0.8.5",
+ "html-webpack-plugin": "^2.9.0",
+ "http-proxy": "^1.12.0",
+ "loaders.css": "^0.1.2",
+ "node-sass": "^3.4.2",
+ "react-addons-css-transition-group": "^0.14.7",
+ "sass-loader": "^3.1.2",
+ "style-loader": "^0.13.0",
+ "webpack": "^1.3.0",
+ "webpack-dev-server": "^1.10.1"
+ }
+}
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+
+var app = require('express').Router();
+var cors = require('cors');
+var utils = require('../../framework/core/api_utils/utils.js')
+var ro = require('./api/ro.js')
+ // Begin Accounts API
+ app.get('/resource-orchestrator', cors(), function(req, res) {
+ ro.get(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+ });
+ app.put('/resource-orchestrator', cors(), function(req, res) {
+ ro.update(req).then(function(data) {
+ utils.sendSuccessResponse(data, res);
+ }, function(error) {
+ utils.sendErrorResponse(error, res);
+ });
+ })
+
+ utils.passThroughConstructor(app);
+
+module.exports = app;
--- /dev/null
+#!/bin/bash
+
+# STANDARD_RIFT_IO_COPYRIGHT
+
+PLUGIN_NAME=accounts
+# change to the directory of this script
+THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
+cd $THIS_DIR
+cd ..
+
+echo 'Building plugin '$PLUGIN_NAME
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME
+npm install
+echo 'Fetching third-party node_modules for '$PLUGIN_NAME'...done'
+echo 'Packaging '$PLUGIN_NAME' using webpack'
+ui_plugin_cmake_build=true ./node_modules/.bin/webpack --progress --config webpack.production.config.js
+echo 'Packaging '$PLUGIN_NAME' using webpack... done'
+echo 'Building plugin '$PLUGIN_NAME'... done'
--- /dev/null
+#!/bin/bash
+
+# STANDARD_RIFT_IO_COPYRIGHT
+
+plugin=config
+source_dir=$1
+dest_dir=$2
+bcache_dir=$3
+
+# Create destination and build cache directories
+mkdir -p $dest_dir
+mkdir -p $bcache_dir
+
+# Create necessary directories under dest and cache dirs
+mkdir -p $dest_dir/framework
+mkdir -p $dest_dir/plugins
+mkdir -p $bcache_dir/framework
+mkdir -p $bcache_dir/plugins
+
+# Copy over built plugin's public folder, config.json, routes.js and api folder as per installed_plugins.txt
+mkdir -p $dest_dir/plugins/$plugin
+cp -Lrf $source_dir/public $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $dest_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $dest_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $dest_dir/plugins/$plugin/.
+tar -cf $dest_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $dest_dir/plugins/$plugin/.
+mkdir -p $bcache_dir/plugins/$plugin
+cp -Lrf $source_dir/public $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/config.json $bcache_dir/plugins/$plugin/.
+cp -Lrf $source_dir/routes.js $bcache_dir/plugins/$plugin/.
+cp -Lrp $source_dir/api $bcache_dir/plugins/$plugin/.
+tar -cf $bcache_dir/plugins/$plugin/node_modules.tar $source_dir/node_modules $source_dir/package.json
+#cp -Lrp $source_dir/node_modules $bcache_dir/plugins/$plugin/.
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+
+var express = require('express');
+var path = require('path');
+var httpProxy = require('http-proxy');
+var bodyParser = require('body-parser');
+var cors = require('cors');
+var session = require('express-session');
+var proxy = httpProxy.createProxyServer();
+var app = express();
+
+var isProduction = process.env.NODE_ENV === 'production';
+var port = isProduction ? 8080 : 8888;
+var publicPath = path.resolve(__dirname, 'public');
+
+if (!isProduction) {
+
+ //Routes for local development
+ var lpRoutes = require('./routes.js');
+
+ app.use(express.static(publicPath));
+ app.use(session({
+ secret: 'ritio rocks',
+ }));
+ app.use(bodyParser.urlencoded({
+ extended: true
+ }));
+ app.use(bodyParser.json());
+ app.use(cors());
+ app.use('/', lpRoutes);
+ var bundle = require('./server/bundle.js');
+ bundle();
+
+ app.all('/build/*', function (req, res) {
+ proxy.web(req, res, {
+ target: 'http://localhost:8080'
+ });
+ });
+
+}
+proxy.on('error', function(e) {
+ console.log('Could not connect to proxy, please try again...');
+});
+
+app.listen(port, function () {
+ console.log('Server running on port ' + port);
+});
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+@import "style/_colors.scss";
+.Config {
+ -ms-flex: 1 1 100%;
+ flex: 1 1 100%;
+
+ .refreshStatus {
+ margin-left: 0.5rem;
+ padding: 1rem 0;
+
+ .currentStatus {
+ text-transform: uppercase;
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-line-pack:center;
+ align-content:center;
+ }
+ span.oi {
+ cursor: pointer;
+ }
+ }
+ .delete, .cancel {
+ cursor: pointer;
+ }
+ .associateSdnAccount {
+ margin: 1rem;
+ }
+ .create > .flex-row > li {
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ margin: 0 .25rem;
+ }
+ .create > .flex-row > li:first-child {
+ margin-left: .5rem;
+ }
+ .create > .flex-row > li:last-child {
+ margin-right: .5rem;
+ }
+ /* .flex-row > li h3 {*/
+ /* background-color: #ffffff;*/
+ /* padding: 12px 18px;*/
+ /* text-transform: uppercase;*/
+ /* }*/
+ .create .options {
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ text-align: center;
+ margin: 24px auto;
+ width: 90%;
+ flex-wrap: wrap;
+ margin: 24px auto;
+ width: 90%;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ }
+ .create .options a {
+ background-color: #ffffff;
+ -ms-flex: 0 1 32%;
+ flex: 0 1 32%;
+ margin: 0 4px 4px 0;
+ padding: 4px;
+ box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+ }
+ .create .options a h5 {
+ font-size: 10px;
+ margin: 5px 0 0 5px;
+ text-align: left;
+ }
+ .create .options a img {
+ margin-top: 10px;
+ width: 70%;
+ }
+ .list-pools {
+ padding: 24px;
+ }
+ .list-pools li a {
+ background-color: #ffffff;
+ display: block;
+ font-size: 12px;
+ margin-bottom: 24px;
+ padding: 12px;
+ text-align: center;
+ box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+ }
+ .list-pools li h4 {
+ text-align: left;
+ }
+ .list-pools li img {
+ margin-top: 24px;
+ width: 65%;
+ }
+ .form-actions {
+ clear: both;
+ margin-top: 36px;
+ text-align: center;
+ margin-bottom:1rem;
+ }
+ .form-actions a {
+ color: #000000;
+ display: inline-block;
+ font-size: 12px;
+ padding: 8px 64px;
+ text-decoration: none;
+ text-transform: uppercase;
+ box-shadow: 2px 2px rgba(0, 0, 0, 0.15);
+ }
+ .form-actions a.save {
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ border-top: 0;
+ cursor: pointer;
+ margin-right: 48px;
+ }
+ .form-actions a.launch {
+ background-color: #333333;
+ border: 1px solid #000000;
+ border-top: 0;
+ color: #ffffff;
+ }
+ .form-actions a.launch:hover, .form-actions a.launch:active {
+ background: #00acee;
+ color: #ffffff;
+ }
+ .create .select-type {
+ margin: 0.5rem;
+ }
+ /* .create-fleet-pool label {*/
+ /* padding: 0.125rem;*/
+ /* display: block;*/
+ /* }*/
+ /* .create-fleet-pool input {*/
+ /* width: 350px;*/
+ /* height: 35px;*/
+ /* margin: 0px 20px 10px 15px;*/
+ /* box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;*/
+ /* font-size: 20px;*/
+ /* }*/
+ .create .optional {
+ font-style: italic;
+ }
+ .name-input input {
+ background:white !important;
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.39), 0 -1px 1px #ffffff, 0 1px 0 #ffffff;
+ display: block;
+ font-size: 120%;
+ height: 35px;
+ margin: 0;
+ margin-top: 0.25rem;
+ width: 350px;
+ }
+ .select-type {
+ display:-ms-flexbox;
+ display:flex;
+ }
+ .accountSelection {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex:0 1;
+ flex:0 1;
+ position:relative;
+ -ms-flex-direction:column;
+ flex-direction:column;
+ margin-right:0.5rem;
+ -ms-flex-align:center;
+ align-items:center;
+ border-top:$gray-light 1px solid;
+ border-left:$gray-light 1px solid;
+ border-right:$gray-dark 1px solid;
+ border-bottom:$gray-dark 1px solid;
+ box-shadow: $gray 2px 2px 3px;
+ cursor:pointer;
+ background:white;
+ &:last-child {
+ margin-right:0;
+ }
+
+ input[type="radio"] {
+ opacity: 0.01;
+ position:absolute;
+ top:0;
+ }
+ &-imageWrapper {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-direction:column;
+ flex-direction:column;
+ margin:0.5rem;
+ padding:0.25rem;
+ background:white;
+ width:100px;
+ height:50px;
+ -ms-flex-align:center;
+ align-items:center;
+ -ms-flex-pack:center;
+ justify-content:center;
+ img{
+ max-width:100px;
+ max-height:50px;
+ }
+ }
+ span {
+ padding-bottom:0.5rem;
+ }
+ &-overlay {
+ position:absolute;
+ top:0;
+ left:0;
+ right:0;
+ bottom:0;
+ height:100%;
+ width:100%;
+ background: rgba(0, 0, 0, 0.25);
+ opacity: 0.2;
+ }
+ &--isSelected{
+ border-bottom:$gray-light 1px solid;
+ border-right:$gray-light 1px solid;
+ border-top:$gray-dark 1px solid;
+ border-left:$gray-dark 1px solid;
+ box-shadow: $gray 2px 2px 3px inset;
+ }
+ }
+ .configForm {
+ margin:0.5rem 0;
+ width:100%;
+ background: $gray-lighter;
+ &-title {
+ background-color: #ffffff;
+ padding: 12px 0.5rem;
+ text-transform: uppercase;
+ &--edit {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-pack:justify;
+ justify-content:space-between;
+ -ms-flex-align: center;
+ align-items: center;
+ >div {
+ display:-ms-flexbox;
+ display:flex;
+ -ms-flex-align:center;
+ align-items:center;
+ }
+ }
+ }
+ img {
+ height:2rem;
+ margin:0 0.5rem;
+ }
+ &-content {
+ padding:0.5rem;
+ }
+ &-nestedParams {
+ display:-ms-flexbox;
+ display:flex;
+ > label {
+ margin-right:0.5rem;
+ }
+ > label:last-child {
+ margin-right:0rem;
+ }
+
+ }
+ }
+ .row {
+ display:-ms-flexbox;
+ display:flex;
+ }
+}
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+module.exports = function(Alt) {
+ return Alt.generateActions(
+ 'getResourceOrchestratorSuccess',
+ 'updateResourceOrchestratorSuccess'
+ );
+}
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import $ from 'jquery';
+var Utils = require('utils/utils.js');
+let API_SERVER = require('utils/rw.js').getSearchParams(window.location).api_server;
+let HOST = API_SERVER;
+let NODE_PORT = require('utils/rw.js').getSearchParams(window.location).api_port || ((window.location.protocol == 'https:') ? 8443 : 8000);
+let DEV_MODE = require('utils/rw.js').getSearchParams(window.location).dev_mode || false;
+
+if (DEV_MODE) {
+ HOST = window.location.protocol + '//' + window.location.hostname;
+}
+
+
+module.exports = function(Alt) {
+ return {
+ getResourceOrchestrator: {
+ remote: function() {
+ return new Promise(function(resolve, reject) {
+ $.ajax({
+ url: 'passthrough/data/api/running/resource-orchestrator' + '?api_server=' + API_SERVER,
+ type: 'GET',
+ beforeSend: Utils.addAuthorizationStub,
+ contentType: "application/json",
+ success: function(data) {
+ resolve(data["rw-launchpad:resource-orchestrator"]);
+ },
+ error: function(error) {
+ console.log("There was an error updating the account: ", arguments);
+
+ }
+ }).fail(function(xhr){
+ //Authentication and the handling of fail states should be wrapped up into a connection class.
+ Utils.checkAuthentication(xhr.status);
+ return reject('error');
+ });
+ });
+ },
+ interceptResponse: interceptResponse({
+ 'error': 'There was an error retrieving the resource orchestrator information.'
+ }),
+ success: Alt.actions.global.getResourceOrchestratorSuccess,
+ loading: Alt.actions.global.showScreenLoader,
+ error: Alt.actions.global.showNotification
+ },
+ update: {
+ remote: function(state, account) {
+
+ return new Promise(function(resolve, reject) {
+ $.ajax({
+ url: 'resource-orchestrator' + '?api_server=' + API_SERVER,
+ type:'PUT',
+ beforeSend: Utils.addAuthorizationStub,
+ data: JSON.stringify(account),
+ contentType: "application/json",
+ success: function(data) {
+ resolve({data});
+ },
+ error: function(error) {
+ console.log("There was an error updating the account: ", arguments);
+ return null;
+ }
+ }).fail(function(xhr){
+ //Authentication and the handling of fail states should be wrapped up into a connection class.
+ Utils.checkAuthentication(xhr.status);
+ return reject('error');
+ });
+
+ });
+ },
+ interceptResponse: interceptResponse({
+ 'error': 'There was an error updating the account.'
+ }),
+ success: Alt.actions.global.updateResourceOrchestratorSuccess,
+ loading: Alt.actions.global.showScreenLoader,
+ error: Alt.actions.global.showNotification
+ }
+ }
+}
+
+function interceptResponse (responses) {
+ return function(data, action, args) {
+ if(responses.hasOwnProperty(data)) {
+ return {
+ type: data,
+ msg: responses[data]
+ }
+ } else {
+ return data;
+ }
+ }
+}
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import AccountActions from './configActions.js';
+import AccountSource from './configSource.js';
+
+let tempData = {
+ "rw-launchpad:resource-orchestrator": {
+ "name": "test",
+ "account-type": "openmano",
+ "openmano": {
+ "port": 9090,
+ "tenant-id": "d2581f60-4f28-11e6-9732-fa163e4bfd3e",
+ "host": "10.0.55.39"
+ }
+ }
+}
+
+var rw = require('utils/rw.js');
+var altImage = rw.getSearchParams(window.location).alt_image;
+
+let Params = {
+ //Config Agent
+ ConfigAgent: {
+
+ }
+}
+
+
+
+let AccountMeta = {
+ 'account-types': ['openmano', 'rift-ro'],
+ 'rift-ro' : [],
+ 'openmano' : [{
+ label: "Host",
+ ref: 'host'
+ }, {
+ label: "Port",
+ ref: 'port'
+ }, {
+ label: "Tenant ID",
+ ref: 'tenant-id'
+ }],
+ imageByType: {
+ "openmano": altImage || require("../../images/openmano.png"),
+ "rift-ro": require("../../images/riftio.png")
+
+ },
+ labelByType: {
+ "openmano": "OpenStack",
+ "rift-ro": "Cloudsim"
+ }
+}
+
+export default class AccountStore {
+ constructor() {
+ this.account = {};
+ this.accountType = 'openmano';
+ this.refreshingAll = false;
+ this.sdnOptions = [];
+ this.AccountMeta = AccountMeta;
+ this.bindActions(AccountActions(this.alt));
+ this.registerAsync(AccountSource);
+ this.exportPublicMethods({
+ getROAccount: this.getROAccount,
+ handleParamChange: this.handleParamChange,
+ handleNameChange: this.handleNameChange,
+ handleAccountTypeChange: this.handleAccountTypeChange,
+ updateAccount: this.updateAccount,
+ getImage: this.getImage
+ })
+ }
+ setAccountTemplate = (AccountType) => {
+ let state = {};
+ let account = {
+ name: '',
+ 'account-type': AccountType || 'rift-ro',
+ };
+ account[AccountType || 'rift-ro'] = {};
+ state.account = account;
+ state.accountType = AccountType;
+ if (AccountType == this.initialAccountType) {
+ state.account = this.initialAccount;
+ }
+ this.setState(state)
+ }
+ updateAccount = (account) => {
+ this.setState({account:account})
+ }
+ getROAccount = () => {
+ let data = tempData["rw-launchpad:resource-orchestrator"]
+ this.setState({
+ account: data
+ })
+ }
+ handleNameChange = (event) => {
+ var account = this.account;
+ account.name = event.target.value;
+ this.setState(
+ {
+ account:account
+ }
+ );
+ }
+ handleAccountTypeChange = (event) => {
+ var accountType = event.target.value;
+ this.setAccountTemplate(accountType);
+ }
+ handleParamChange(node, event) {
+ return function(event) {
+ var account = this.state.account;
+ account[account['account-type']][node.ref] = event.target.value;
+ this.updateAccount(account);
+ }.bind(this);
+ }
+ getImage = (type) => {
+ return AccountMeta.imageByType[type];
+ }
+ getResourceOrchestratorSuccess = (data) => {
+ this.alt.actions.global.hideScreenLoader.defer();
+ if(data.hasOwnProperty('empty')) {
+ this.setAccountTemplate(false)
+ } else {
+ this.setState({
+ initialAccount: data,
+ initialAccountType: data['account-type'],
+ account: data,
+ accountType: data['account-type'] || 'rift-ro'
+ });
+ }
+ }
+ updateResourceOrchestratorSuccess = (data) => {
+ this.alt.actions.global.showNotification.defer({type:'success', msg: 'Resource Orchestrator has been succesfully updated'});
+ }
+}
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+
+import React from 'react';
+import AppHeader from 'widgets/header/header.jsx';
+import ConfigStore from './configStore.js';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import 'style/layout.scss';
+import './config.scss';
+import {Panel, PanelWrapper} from 'widgets/panel/panel';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import Button from 'widgets/button/rw.button.js';
+
+class ConfigDashboard extends React.Component {
+ constructor(props) {
+ super(props);
+ this.Store = this.props.flux.stores.hasOwnProperty('ConfigStore') ? this.props.flux.stores.ConfigStore : this.props.flux.createStore(ConfigStore);
+ this.state = this.Store.getState();
+ }
+ componentWillMount() {
+ this.Store.listen(this.updateState);
+ this.Store.getResourceOrchestrator();
+ }
+ componentWillUnmount() {
+ this.Store.unlisten(this.updateState);
+ }
+ updateState = (state) => {
+ this.setState(state);
+ }
+ updateAccount = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.Store.update(this.state.account);
+ }
+ render() {
+ let self = this;
+ let html;
+ let Account = this.state.account;
+ let AccountMeta = this.state.AccountMeta;
+ let AccountType = this.state.accountType;
+ let isEdit = true;
+ let ParamsHTML = null;
+ let Store = this.Store;
+ let Types = this.state.AccountMeta['account-types'];
+
+ let selectAccountStack = [];
+ let selectAccountHTML = null;
+
+
+ if (Account['account-type']) {
+ for (var i = 0; i < Types.length; i++) {
+ var node = Types[i];
+ var isSelected = (Account['account-type'] == node);
+ selectAccountStack.push(
+ <label key={i} className={"accountSelection " + (isSelected ? "accountSelection--isSelected" : "")}>
+ <div className={"accountSelection-overlay" + (isSelected ? "accountSelection-overlay--isSelected" : "")}></div>
+ <div className="accountSelection-imageWrapper">
+ <img src={Store.getImage(node)}/>
+ </div>
+ <input type="radio" name="account"
+ onChange={Store.handleAccountTypeChange} defaultChecked={node == Types[0]} value={node} />{node}
+ </label>
+ )
+ }
+ selectAccountHTML = (
+ <Panel className="accountForm" title="Select Account Type" no-corners>
+ <div className="select-type accountForm-content row" >
+ {selectAccountStack}
+ </div>
+ </Panel>
+ );
+ }
+
+ if (AccountMeta[AccountType] && AccountMeta[AccountType].length > 0) {
+ var paramsStack = [];
+ var optionalField = '';
+ for (var i = 0; i < AccountMeta[AccountType].length; i++) {
+ var node = AccountMeta[AccountType][i];
+ var value = ""
+ if (Account[AccountType]) {
+ value = Account[AccountType][node.ref]
+ }
+ paramsStack.push(
+ <TextInput key={node.label} className="accountForm-input" label={node.label} required={!node.optional} onChange={this.Store.handleParamChange(node)} value={value} />
+ );
+ }
+ ParamsHTML = (
+ <Panel className="create-fleet-pool accountForm" title={(isEdit ? 'Update' : 'Enter') + ' Account Details'} no-corners>
+ <div className="accountForm-content">
+ {paramsStack}
+ </div>
+ </Panel>
+ )
+ } else {
+ ParamsHTML = (
+ <Panel className="create-fleet-pool accountForm" title={(isEdit ? 'Update' : 'Enter') + ' Account Details'} no-corners>
+ <label style={{'marginLeft':'17px', color:'#888'}}>No Details Required</label>
+ </Panel>
+ )
+ }
+
+
+
+ html = (
+ <PanelWrapper className="column Config" style={{'alignContent': 'center', 'flexDirection': 'column'}}>
+ <form className="app-body create Accounts" onSubmit={this.preventDefault} onKeyDown={this.evaluateSubmit}>
+ <div className="noticeSubText noticeSubText_right">
+ * required
+ </div>
+ <div>
+ <Panel className="create-fleet-pool accountForm" title="Resource Orchestrator" no-corners>
+ <div className="accountForm-content">
+ <TextInput className="accountForm-input" label={"Name"} onChange={this.Store.handleNameChange} value={Account.name} />
+ </div>
+ </Panel>
+
+ {
+ selectAccountHTML
+ }
+ {
+ ParamsHTML
+ }
+ </div>
+ <div className="form-actions">
+ <Button className="light" label="Cancel" />
+ <Button key="4" role="button" className="update dark" label="Update" onClick={this.updateAccount} />
+ </div>
+ </form>
+ </PanelWrapper>
+ );
+ return html;
+ }
+}
+// onClick={this.Store.update.bind(null, Account)}
+ConfigDashboard.contextTypes = {
+ router: React.PropTypes.object
+};
+
+export default SkyquakeComponent(ConfigDashboard);
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+
+import React from 'react';
+import Button from 'widgets/button/rw.button.js';
+import _ from 'lodash';
+import SkyquakeComponent from 'widgets/skyquake_container/skyquakeComponent.jsx';
+import Crouton from 'react-crouton';
+import TextInput from 'widgets/form_controls/textInput.jsx';
+import 'style/common.scss';
+import './config.scss';
+class Account extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {};
+ this.state.account = {};
+ }
+ storeListener = (state) => {
+ if(!state.account) {
+ this.setUp(this.props)
+ }
+ state.account && this.setState({account: state.account,accountType: state.accountType, types: state.types, sdnOptions: state.sdnOptions})
+ }
+ componentWillMount() {
+ this.props.store.listen(this.storeListener);
+ this.setUp(this.props);
+ }
+ componentWillReceiveProps(nextProps) {
+ if(JSON.stringify(nextProps.params) != JSON.stringify(this.props.params)){
+ this.setUp(nextProps);
+ }
+ }
+ componentWillUnmount() {
+ this.props.store.unlisten(this.storeListener);
+ }
+ setUp(props){
+ if(props.params.name != 'create') {
+ this.props.store.viewAccount({type: props.params.type, name: props.params.name});
+ } else {
+ this.props.store.setAccountTemplate(props.params.type);
+ }
+ }
+ create(e) {
+ e.preventDefault();
+ var self = this;
+ var Account = this.state.account;
+ let AccountType = this.state.accountType;
+ if (Account.name == "") {
+ self.props.flux.actions.global.showNotification("Please give the account a name");
+ return;
+ } else {
+ var type = Account['account-type'];
+ var params = Account.params;
+
+ if(params) {
+ for (var i = 0; i < params.length; i++) {
+ var param = params[i].ref;
+ if (typeof(Account[type]) == 'undefined' || typeof(Account[type][param]) == 'undefined' || Account[type][param] == "") {
+ if (!params[i].optional) {
+ self.props.flux.actions.global.showNotification("Please fill all account details");
+ return;
+ }
+ }
+ }
+ }
+
+ let nestedParams = Account.nestedParams && Account.nestedParams;
+ if (nestedParams && nestedParams.params) {
+ for (let i = 0; i < nestedParams.params.length; i++) {
+ let nestedParam = nestedParams.params[i].ref;
+ if (typeof(Account[type]) == 'undefined' || typeof(Account[type][nestedParams['container-name']][nestedParam]) == 'undefined' || Account[type][nestedParams['container-name']][nestedParam] == "") {
+ if (!nestedParams.params[i].optional) {
+ self.props.flux.actions.global.showNotification("Please fill all account details");
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ let newAccount = _.cloneDeep(removeTrailingWhitespace(Account));
+ delete newAccount.params;
+ newAccount.nestedParams &&
+ newAccount.nestedParams['container-name'] &&
+ delete newAccount[newAccount.nestedParams['container-name']];
+ delete newAccount.nestedParams;
+
+ this.props.flux.actions.global.showScreenLoader();
+ this.props.store.create(newAccount, AccountType).then(function() {
+ self.props.router.push({pathname:'accounts'});
+ self.props.flux.actions.global.hideScreenLoader.defer();
+ },
+ function() {
+ self.props.flux.actions.global.showNotification("There was an error creating your account. Please contact your system administrator.");
+ self.props.flux.actions.global.hideScreenLoader.defer();
+ });
+ }
+ update(e) {
+ e.preventDefault();
+ var self = this;
+ var Account = this.state.account;
+ let AccountType = this.state.accountType;
+ this.props.flux.actions.global.showScreenLoader();
+ this.props.store.update(Account, AccountType).then(function() {
+ self.props.router.push({pathname:'accounts'});
+ self.props.flux.actions.global.hideScreenLoader();
+ },
+ function() {
+
+ });
+ }
+ cancel = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ this.props.router.push({pathname:'accounts'});
+ }
+ handleDelete = () => {
+ let self = this;
+ let msg = 'Preparing to delete "' + self.state.account.name + '"' +
+ ' Are you sure you want to delete this ' + self.state.accountType + ' account?"';
+ if (window.confirm(msg)) {
+ this.props.store.delete(self.state.accountType, self.state.account.name).then(function() {
+ self.props.flux.actions.global.hideScreenLoader();
+ self.props.router.push({pathname:'accounts'});
+ }, function(){
+ // self.props.flux.actions.global.hideScreenLoader.defer();
+ // console.log('Delete Account Fail');
+ });
+ } else {
+ self.props.flux.actions.global.hideScreenLoader();
+ }
+ }
+ handleNameChange(event) {
+ this.props.store.handleNameChange(event);
+ }
+ handleAccountTypeChange(node, event) {
+ this.props.store.handleAccountTypeChange(node, event);
+ }
+ handleSelectSdnAccount = (e) => {
+ var tmp = this.state.account;
+ if(e) {
+ tmp['sdn-account'] = e;
+ } else {
+ if(tmp['sdn-account']) {
+ delete tmp['sdn-account'];
+ }
+ }
+ console.log(e, tmp)
+ }
+ preventDefault = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ evaluateSubmit = (e) => {
+ if (e.keyCode == 13) {
+ if (this.props.edit) {
+ this.update(e);
+ } else {
+ this.create(e);
+ }
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+
+ render() {
+ let self = this;
+ let {store, ...props} = this.props;
+ // This section builds elements that only show up on the create page.
+ // var name = <label>Name <input type="text" onChange={this.handleNameChange.bind(this)} style={{'textAlign':'left'}} /></label>;
+ var name = <TextInput label="Name" onChange={this.handleNameChange.bind(this)} required={true} />;
+ let params = null;
+ let selectAccount = null;
+ let resfreshStatus = null;
+ let Account = this.state.account;
+ // AccountType is for the view, not the data account-type value;
+ let AccountType = this.state.accountType;
+ let Types = this.state.types;
+ let isEdit = this.props.params.name != 'create';
+ var buttons;
+ let cloudResources = Account['cloud-resources-state'] && Account['cloud-resources-state'][Account['account-type']];
+ let cloudResourcesStateHTML = null;
+
+ // Account Type Radio
+ var selectAccountStack = [];
+ if (!isEdit) {
+ buttons = [
+ <Button key="0" onClick={this.cancel} className="cancel light" label="Cancel"></Button>,
+ <Button key="1" role="button" onClick={this.create.bind(this)} className="save dark" label="Save" />
+ ]
+ for (var i = 0; i < Types.length; i++) {
+ var node = Types[i];
+ var isSelected = (Account['account-type'] == node['account-type']);
+ selectAccountStack.push(
+ <label key={i} className={"accountSelection " + (isSelected ? "accountSelection--isSelected" : "")}>
+ <div className={"accountSelection-overlay" + (isSelected ? "accountSelection-overlay--isSelected" : "")}></div>
+ <div className="accountSelection-imageWrapper">
+ <img src={store.getImage(node['account-type'])}/>
+ </div>
+ <input type="radio" name="account" onChange={this.handleAccountTypeChange.bind(this, node)} defaultChecked={node.name == Types[0].name} value={node['account-type']} />{node.name}
+ </label>
+ )
+ }
+ selectAccount = (
+ <div className="accountForm">
+ <h3 className="accountForm-title">Select Account Type</h3>
+ <div className="select-type accountForm-content" >
+ {selectAccountStack}
+ </div>
+ </div>
+ );
+ } else {
+ selectAccount = null
+ }
+
+ //
+ // This sections builds the parameters for the account details.
+ if (Account.params) {
+ var paramsStack = [];
+ var optionalField = '';
+ for (var i = 0; i < Account.params.length; i++) {
+ var node = Account.params[i];
+ var value = ""
+ if (Account[Account['account-type']]) {
+ value = Account[Account['account-type']][node.ref]
+ }
+ if (this.props.edit && Account.params) {
+ value = Account.params[node.ref];
+ }
+ paramsStack.push(
+ <TextInput key={node.label} className="accountForm-input" label={node.label} required={!node.optional} onChange={this.props.store.handleParamChange(node)} value={value} />
+ );
+ }
+ params = (
+ <li className="create-fleet-pool accountForm">
+ <h3 className="accountForm-title"> {isEdit ? 'Update' : 'Enter'} Account Details</h3>
+ <div className="accountForm-content">
+ {paramsStack}
+ </div>
+ </li>
+ )
+ } else {
+ params = (
+ <li className="create-fleet-pool accountForm">
+ <h3 className="accountForm-title"> {isEdit ? 'Update' : 'Enter'}</h3>
+ <label style={{'marginLeft':'17px', color:'#888'}}>No Details Required</label>
+ </li>
+ )
+ }
+
+ // This section builds elements that only show up in the edit page.
+ if (isEdit) {
+ name = <label>{Account.name}</label>;
+ buttons = [
+ <Button key="2" onClick={this.handleDelete} className="light" label="Remove Account" />,
+ <Button key="3" onClick={this.cancel} className="light" label="Cancel" />,
+ <Button key="4" role="button" onClick={this.update.bind(this)} className="update dark" label="Update" />
+ ];
+ resfreshStatus = Account['connection-status'] ? (
+ <div className="accountForm">
+ <div className="accountForm-title accountForm-title--edit">
+ Connection Status
+ </div>
+ <div className="accountForm-content" style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+ <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+ <AccountConnectivityStatus status={Account['connection-status'].status} />
+ {Account['connection-status'].status.toUpperCase()}
+ </div>
+ <Button className="refreshList light" onClick={this.props.store.refreshAccount.bind(this, Account.name, AccountType)} label="REFRESH STATUS"></Button>
+ </div>
+ {
+ Account['connection-status'].status.toUpperCase() === 'FAILURE' ?
+ displayFailureMessage(Account['connection-status'].details) : null
+ }
+ </div>
+ ) : null;
+ // cloudResourcesStateHTML = (
+ // <div className="accountForm">
+ // <h3 className="accountForm-title">Resources Status</h3>
+ // <div className="accountForm-content" >
+ // <ul>
+ // {
+ // cloudResources && props.AccountMeta.resources[Account['account-type']].map(function(r, i) {
+
+ // return (
+ // <li key={i}>
+ // {r}: {cloudResources[r]}
+ // </li>
+ // )
+ // }) || 'No Additional Resources'
+ // }
+ // </ul>
+ // </div>
+ // </div>
+ // )
+ }
+
+ var html = (
+
+ <form className="app-body create Accounts" onSubmit={this.preventDefault} onKeyDown={this.evaluateSubmit}>
+ <div className="noticeSubText noticeSubText_right">
+ * required
+ </div>
+ <div className="associateSdnAccount accountForm">
+ <h3 className="accountForm-title">Account</h3>
+ <div className="accountForm-content" style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+ <h4 style={{flex: '1'}}>{name}</h4>
+ { isEdit ?
+ (
+ <div style={{display: 'flex', justifyContent: 'space-between', alignItems: 'center'}}>
+ <img src={store.getImage(Account['account-type'])}/> {props.AccountMeta.labelByType[Account['account-type']]}
+ </div>)
+ : null
+ }
+ </div>
+ </div>
+
+ {selectAccount}
+ {sdnAccounts}
+ {resfreshStatus}
+ {cloudResourcesStateHTML}
+ <ol className="flex-row">
+ {params}
+ </ol>
+ <div className="form-actions">
+ {buttons}
+ </div>
+ </form>
+ )
+ return html;
+ }
+}
+
+function displayFailureMessage(msg) {
+ return (
+ <div className="accountForm-content" style={{maxWidth: '600px'}}>
+ <div style={{paddingBottom: '1rem'}}>Details:</div>
+ <div>
+ {msg}
+ </div>
+
+ </div>
+ )
+}
+
+class SelectOption extends React.Component {
+ constructor(props){
+ super(props);
+ }
+ handleOnChange = (e) => {
+ this.props.onChange(JSON.parse(e.target.value));
+ }
+ render() {
+ let html;
+ html = (
+ <select className={this.props.className} onChange={this.handleOnChange}>
+ {
+ this.props.options.map(function(op, i) {
+ return <option key={i} value={JSON.stringify(op.value)}>{op.label}</option>
+ })
+ }
+ </select>
+ );
+ return html;
+ }
+}
+SelectOption.defaultProps = {
+ options: [],
+ onChange: function(e) {
+ console.dir(e)
+ }
+}
+
+function removeTrailingWhitespace(Account) {
+ var type = Account['account-type'];
+ var params = Account.params;
+
+ if(params) {
+ for (var i = 0; i < params.length; i++) {
+ var param = params[i].ref;
+ if(typeof(Account[type][param]) == 'string') {
+ Account[type][param] = Account[type][param].trim();
+ }
+ }
+ }
+
+ let nestedParams = Account.nestedParams;
+ if (nestedParams && nestedParams.params) {
+ for (let i = 0; i < nestedParams.params.length; i++) {
+ let nestedParam = nestedParams.params[i].ref;
+ let nestedParamValue = Account[type][nestedParams['container-name']][nestedParam];
+ if (typeof(nestedParamValue) == 'string') {
+ Account[type][nestedParams['container-name']][nestedParam] = nestedParamValue.trim();
+ }
+ }
+ }
+ return Account;
+}
+
+export default SkyquakeComponent(Account)
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+import "babel-polyfill";
+import { render } from 'react-dom';
+import SkyquakeRouter from 'widgets/skyquake_container/skyquakeRouter.jsx';
+const config = require('json!../config.json');
+
+let context = require.context('./', true, /^\.\/.*\.jsx$/);
+let router = SkyquakeRouter(config, context);
+let element = document.querySelector('#app');
+
+render(router, element);
+
+
--- /dev/null
+/*
+ * STANDARD_RIFT_IO_COPYRIGHT
+ */
+var Webpack = require('webpack');
+var path = require('path');
+var nodeModulesPath = path.resolve(__dirname, 'node_modules');
+var buildPath = path.resolve(__dirname, 'public', 'build');
+var mainPath = path.resolve(__dirname, 'src', 'main.js');
+var uiPluginCmakeBuild = process.env.ui_plugin_cmake_build || false;
+var frameworkPath = uiPluginCmakeBuild?'../../../../skyquake/skyquake-build/framework':'../../framework';
+var HtmlWebpackPlugin = require('html-webpack-plugin');
+var CommonsPlugin = new require("webpack/lib/optimize/CommonsChunkPlugin")
+// Added to overcome node-sass bug https://github.com/iam4x/isomorphic-flux-boilerplate/issues/62
+process.env.UV_THREADPOOL_SIZE=64;
+var config = {
+ devtool: 'source-map',
+ entry: mainPath,
+ output: {
+ path: buildPath,
+ filename: 'bundle.js',
+ publicPath: "build/"
+ },
+ resolve: {
+ extensions: ['', '.js', '.jsx', '.css', '.scss'],
+ root: path.resolve(frameworkPath),
+ alias: {
+ 'widgets': path.resolve(frameworkPath) + '/widgets',
+ 'style': path.resolve(frameworkPath) + '/style',
+ 'utils': path.resolve(frameworkPath) + '/utils'
+ }
+ },
+ module: {
+ loaders: [{
+ test: /\.(jpe?g|png|gif|svg|ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/i,
+ loader: "file-loader"
+ },
+ {
+ test: /\.(js|jsx)$/,
+ exclude: /react-treeview/,
+ loader: 'babel-loader',
+ query: {
+ presets: ["es2015", "stage-0", "react"]
+ }
+ }, {
+ test: /\.css$/,
+ loader: 'style!css'
+ }, {
+ test: /\.scss/,
+ loader: 'style!css!sass?includePaths[]='+ path.resolve(frameworkPath)
+ }
+ ]
+ },
+ plugins: [
+ new HtmlWebpackPlugin({
+ filename: '../index.html'
+ , templateContent: '<div id="app"></div>'
+ }),
+ new Webpack.optimize.CommonsChunkPlugin("vendor", "vendor.js", Infinity)
+ ]
+};
+module.exports = config;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
'Authorization': req.get('Authorization')
});
request({
- url: utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters/cloud-accounts?deep',
+ url: utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters?deep',
method: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
if (utils.validateResponse('DataCenters.get', error, response, body, resolve, reject)) {
var returnData = {};
try {
- data = JSON.parse(response.body)['rw-launchpad:cloud-accounts'];
+ data = JSON.parse(response.body)["rw-launchpad:datacenters"]["ro-accounts"];
data.map(function(c) {
returnData[c.name] = c.datacenters;
})
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
asyncOperations.push(this.Store.getCatalog());
asyncOperations.push(this.Store.getCloudAccount(function() {
asyncOperations.push(self.Store.getDataCenters());
+ asyncOperations.push(self.Store.getResourceOrchestrator());
asyncOperations.push(self.Store.getSshKey());
asyncOperations.push(self.Store.getConfigAgent());
+ asyncOperations.push(self.Store.getResourceOrchestrator());
}));
Promise.all(asyncOperations).then(function(resolve, reject) {
if(self.props.params.nsd) {
self.props.actions.showNotification('Spaces and special characters except underscores are not supported in the network service name at this time');
return;
}
- if (this.isOpenMano() && (this.state.dataCenterID == "" || !this.state.dataCenterID)) {
+ if (this.state.isOpenMano && (this.state.dataCenterID == "" || !this.state.dataCenterID)) {
self.props.actions.showNotification("Please enter the Data Center ID");
return;
}
return !this.props.location.pathname.split('/')[2];
}
isOpenMano = () => {
- return this.state.selectedCloudAccount['account-type'] == 'openmano';
+ return this.state.ro['account-type'] == 'openmano';
}
openDescriptor = (descriptor) => {
let NSD = descriptor;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
<div className="configure-nsd_section">
<div className="inputControls">
<TextInput label="Instance Name" type="text" pattern="^[a-zA-Z0-9_]*$" style={{textAlign:'left'}} onChange={props.updateName} value={props.name}/>
- <label>Select VIM Account
- <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} onChange={props.nsFn.updateSelectedCloudAccount} />
- </label>
{
- isOpenMano(props.selectedCloudAccount) ? this.dataCentersHTML(props.dataCenters[selectedCloudAccount.name], props.nsFn.updateSelectedDataCenter) : null
+ !isOpenMano(props.ro) ?
+ (
+ <label>Select VIM Account
+ <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} onChange={props.nsFn.updateSelectedCloudAccount} />
+ </label>
+ )
+ : null
+ }
+ {
+ isOpenMano(props.ro) ?
+ dataCentersHTML(props.dataCenters[props.ro.name],
+ props.nsFn.updateSelectedDataCenter)
+ : null
}
</div>
</div>
return (
<div className="inputControls" key={i}>
<h4 className="inputControls-title">VNFD: {v.name}</h4>
- <label>Select VIM Account
- <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} initial={true} onChange={props.vnfFn.updateSelectedCloudAccount.bind(v['member-vnf-index'])} defaultValue={defaultValue} />
- </label>
+ {
+ !isOpenMano(props.ro) ?
+ (
+ <label>Select VIM Account
+ <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} initial={true} onChange={props.vnfFn.updateSelectedCloudAccount.bind(v['member-vnf-index'])} defaultValue={defaultValue} />
+ </label>
+ )
+ : null
+ }
{
- isOpenMano(defaultValue) ? dataCentersHTML(dataCenters[defaultValue.account.name], props.vnfFn.updateSelectedDataCenter(v['member-vnf-index'])) : null
+ isOpenMano(props.ro) ?
+ dataCentersHTML(
+ props.dataCenters[props.ro.name],
+ props.vnfFn.updateSelectedDataCenter.bind(null, v['member-vnf-index']))
+ : null
}
{
(props.configAgentAccounts && props.configAgentAccounts.length > 0) ?
});
return CloudAccountOptions;
}
-function dataCentersHTML(state, onChange) {
+function dataCentersHTML(dataCenters, onChange) {
//Build DataCenter options
//Relook at this, why is it an object?
- let dataCenters = state.dataCenters || [];
- let DataCenterOptions = {};
- if(dataCenters){
- for (let d in dataCenters) {
- DataCenterOptions[d] = dataCenters[d].map(function(dc, index) {
- return {
- label: dc.name,
- value: dc.uuid
- }
- });
+ let DataCenterOptions = [];
+ DataCenterOptions = dataCenters && dataCenters.map(function(dc, index) {
+ return {
+ label: dc.name,
+ value: dc.uuid
}
- }
- if (dataCenters.length > 0) {
+ });
+ if (dataCenters && dataCenters.length > 0) {
return (
<label>Select Data Center
<SelectOption options={DataCenterOptions} onChange={onChange} />
if (a.constructor.name == 'String') {
a = JSON.parse(a);
}
- if(a.hasOwnProperty('account')) {
- a = a.account;
- }
return a['account-type'] == 'openmano';
} else {
return false;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
cloudAccounts={this.props.cloudAccounts}
selectedCloudAccount={this.props.selectedCloudAccount}
vnfdCloudAccounts={this.props.vnfdCloudAccounts}
+ ro={this.props.ro}
dataCenters={this.props.dataCenters}
configAgentAccounts={this.props.configAgentAccounts}
inputParameters={this.props['input-parameters']}
selectedID={this.props.selectedNSDid}
selectedNSD={selectedNSD}
+ isOpenMano={this.props.isOpenMano}
+
/></Panel>
</PanelWrapper>
)
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
this.selectedNSDid;
this.selectedNSD = {};
this.selectedCloudAccount = {};
- this.dataCenters = {};
+ this.dataCenters = [];
this.cloudAccounts = [];
this.isLoading = false;
this.hasConfigureNSD = false;
this['input-parameters'] = [];
this.displayPlacementGroups = false;
+ this.ro = {};
this.bindActions(NetworkServiceActions);
this.nsdConfiguration = {
name:'',
this.configAgentAccounts = [];
this.isPreviewing = false;
+ this.isOpenMano = false;
this.registerAsync(NetworkServiceSource);
this.exportPublicMethods({
getMockData: getMockData.bind(this),
configAgentAccounts: configAgentAccounts
})
}
- getDataCentersSuccess(dataCenters) {
+ getDataCentersSuccess(data) {
+ let dataCenters = data;
+
let newState = {
- dataCenters: dataCenters
+ dataCenters: dataCenters || []
};
- if (this.selectedCloudAccount['account-type'] == 'openmano') {
- newState.dataCenterID = dataCenters[this.selectedCloudAccount.name][0].uuid
+ if (this.ro['account-type'] == 'openmano') {
+ newState.dataCenterID = dataCenters[this.ro.name][0].uuid
}
this.setState(newState)
}
sshKeysRef: []
})
}
+ getResourceOrchestratorSuccess = (data) => {
+ Alt.actions.global.hideScreenLoader.defer();
+ this.setState({
+ ro: data
+ })
+ }
+ getResourceOrchestratorError = (data) => {
+ console.log('getResourceOrchestrator Error: ', data)
+ }
//Form handlers
nameUpdated = (e) => {
this.setState({
} else {
newState.displayPlacementGroups = false;
}
- if (cloudAccount['account-type'] == 'openmano' && this.dataCenters && self.dataCenters[cloudAccount['name']]) {
- let datacenter = self.dataCenters[cloudAccount['name']][0];
- newState.dataCenterID = datacenter.uuid;
- }
self.setState(newState);
},
updateSelectedDataCenter: (dataCenter) => {
self.setState({
- dataCenterID: dataCenter
+ dataCenterID: dataCenter.target.value
});
},
placementGroupUpdate: (i, k, value) => {
},
updateSelectedDataCenter: (id, dataCenter) => {
let vnfCA = self.vnfdCloudAccounts;
- vnfCA[id].datacenter = dataCenter;
+ if (!vnfCA[id]) {
+ vnfCA[id] = {};
+ }
+ vnfCA[id].datacenter = dataCenter.target.value;
self.setState({
vnfdCloudAccounts: vnfCA
});
"admin-status": launch ? "ENABLED" : "DISABLED",
"nsd": nsdPayload
}
- payload["cloud-account"] = this.state.selectedCloudAccount.name;
- if (this.state.selectedCloudAccount['account-type'] == "openmano") {
+
+ if (this.state.ro['account-type'] == 'openmano') {
payload['om-datacenter'] = this.state.dataCenterID;
+ } else {
+ payload["cloud-account"] = this.state.selectedCloudAccount.name;
}
if (this.state.hasConfigureNSD) {
let ips = this.state['input-parameters'];
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
'getInstantiateSshKeyLoading',
'getInstantiateSshKeyError',
'getConfigAgentSuccess',
- 'getConfigAgentError'
+ 'getConfigAgentError',
+ 'getResourceOrchestratorSuccess',
+ 'getResourceOrchestratorAgentError'
)
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
},
success: Alt.actions.global.getConfigAgentSuccess,
error: Alt.actions.global.getConfigAgentError
+ },
+ getResourceOrchestrator: {
+ remote: function() {
+ return new Promise(function(resolve, reject) {
+ $.ajax({
+ url: 'passthrough/data/api/running/resource-orchestrator' + '?api_server=' + API_SERVER,
+ type: 'GET',
+ beforeSend: Utils.addAuthorizationStub,
+ contentType: "application/json",
+ success: function(data) {
+ resolve(data["rw-launchpad:resource-orchestrator"]);
+ },
+ error: function(error) {
+ console.log("There was an error updating the account: ", arguments);
+
+ }
+ }).fail(function(xhr){
+ //Authentication and the handling of fail states should be wrapped up into a connection class.
+ Utils.checkAuthentication(xhr.status);
+ return reject('error');
+ });
+ });
+ },
+ interceptResponse: interceptResponse({
+ 'error': 'There was an error retrieving the resource orchestrator information.'
+ }),
+ success: Alt.actions.global.getResourceOrchestratorSuccess,
+ loading: Alt.actions.global.showScreenLoader,
+ error: Alt.actions.global.showNotification
+ }
+
}
}
+function interceptResponse (responses) {
+ return function(data, action, args) {
+ if(responses.hasOwnProperty(data)) {
+ return {
+ type: data,
+ msg: responses[data]
+ }
+ } else {
+ return data;
+ }
+ }
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
'instantiateNetworkService',
'setNsListPanelVisible',
'getVDUConsoleLinkSuccess',
- 'getVDUConsoleLinkError'
+ 'getVDUConsoleLinkError',
+ 'getResourceOrchestratorSuccess'
);
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");