<header>
<Link to={'accounts/sdn/' + account.name} title="Edit Account">
<div className="accountSidebarCard--content">
+ <img className="accountSidebarCard--logo" src={store.getImage(account['account-type'])} />
<h3>{account.name}<AccountConnectivityStatus status={status}/></h3>
</div>
</Link>
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
const placeholder = changeCase.title(property.name);
const className = ClassNames(property.name + '-input', {'-is-guid': isGuid});
+ const fieldValue = value ? value.constructor.name == "String" ? value : '' : undefined;
if (isEnumeration) {
const enumeration = Property.getEnumeration(property, value);
const options = enumeration.map((d, i) => {
id={fieldKey.toString()}
type="text"
name={name}
- value={value}
+ value={fieldValue}
className={className}
placeholder={placeholder}
onChange={onChange}
if (typeof value === 'object') {
childValue = value[property.name];
}
- childPath.push(property.name);
-
+ if(property.type != 'choice'){
+ childPath.push(property.name);
+ }
return build(container, property, childPath, childValue);
});
const statePath = ['uiState.choice'].concat(name);
const stateObject = utils.resolvePath(this.model, statePath.join('.')) || {};
+ const selected = stateObject.selected ? stateObject.selected.split('.')[1] : undefined;
// write state back to the model so the new state objects are captured
utils.assignPathValue(this.model, statePath.join('.'), stateObject);
// write the current choice value into the state
- const choiceObject = utils.resolvePath(this.model, [name, stateObject.selected].join('.'));
+ const choiceObject = utils.resolvePath(this.model, [name, selected].join('.'));
if (choiceObject) {
- utils.assignPathValue(stateObject, ['case', stateObject.selected].join('.'), _.cloneDeep(choiceObject));
+ utils.assignPathValue(stateObject, ['case', selected].join('.'), _.cloneDeep(choiceObject));
}
// remove the current choice value from the model
- utils.removePathValue(this.model, [name, stateObject.selected].join('.'));
+ utils.removePathValue(this.model, [name, selected].join('.'));
// get any state for the new selected choice
const newChoiceObject = utils.resolvePath(stateObject, ['case', value].join('.')) || {};
const cases = property.properties.map(d => {
if (d.type === 'case') {
caseByNameMap[d.name] = d.properties[0];
- return {optionName: d.name, optionTitle: d.description};
+ return {
+ optionName: d.name,
+ optionTitle: d.description,
+ //represents case name and case element name
+ optionValue: [d.name, d.properties[0].name].join('.')
+ };
}
caseByNameMap[d.name] = d;
return {optionName: d.name};
const options = [{optionName: ''}].concat(cases).map((d, i) => {
return (
- <option key={i} value={d.optionName} title={d.optionTitle}>
+ <option key={i} value={d.optionValue} title={d.optionTitle}>
{d.optionName}
{i ? null : changeCase.title(property.name)}
</option>
});
const selectName = path.join('.');
- const selectedOptionPath = ['uiState.choice', selectName, 'selected'].join('.');
- const selectedOptionValue = utils.resolvePath(container.model, selectedOptionPath);
- const valueProperty = caseByNameMap[selectedOptionValue] || {properties: []};
-
- const valueResponse = valueProperty.properties.map((d, i) => {
+ let selectedOptionPath = ['uiState.choice', selectName, 'selected'].join('.');
+ //Currently selected choice/case statement on UI model
+ let selectedOptionValue = utils.resolvePath(container.model, selectedOptionPath);
+ //If first time loaded, and none is selected, check if there is a value corresponding to a case statement in the container model
+ if(!selectedOptionValue) {
+ //get field properties for choice on container model
+ let fieldProperties = utils.resolvePath(container.model, selectName);
+ if(fieldProperties) {
+ //Check each case statement in model and see if it is present in container model.
+ cases.map(function(c){
+ if(fieldProperties.hasOwnProperty(c.optionName)) {
+ utils.assignPathValue(container.model, ['uiState.choice', selectName, 'selected'].join('.'), c.optionValue);
+ }
+ });
+ selectedOptionValue = utils.resolvePath(container.model, ['uiState.choice', selectName, 'selected'].join('.'));
+ }
+ }
+ //If selectedOptionValue is present, take first item in string which represents the case name.
+ const valueProperty = caseByNameMap[selectedOptionValue ? selectedOptionValue.split('.')[0] : undefined] || {properties: []};
+ const isLeaf = Property.isLeaf(valueProperty);
+ const hasProperties = _.isArray(valueProperty.properties) && valueProperty.properties.length;
+ const isMissingDescriptorMeta = !hasProperties && !Property.isLeaf(valueProperty);
+ //Some magic that prevents errors for arising
+ const valueResponse = valueProperty.properties.length ? valueProperty.properties.map((d, i) => {
const childPath = path.concat(valueProperty.name, d.name);
const childValue = utils.resolvePath(container.model, childPath.join('.'));
return (
{build(container, d, childPath, childValue, props)}
</div>
);
- });
-
+ }) : (!isMissingDescriptorMeta) ? build(container, valueProperty, path.concat(valueProperty.name), utils.resolvePath(container.model, path.concat(valueProperty.name).join('.'))) : null
+ // end magic
const onFocus = onFocusPropertyFormInputElement.bind(container, property, path, value);
return (
throw new ReferenceError('child must be an instance of DescriptorModel class');
}
if (this.findChildByUid(child.uid)) {
- throw new ReferenceError('child already exists');
+ console.warn('Child already exists');
+ // NOTE: Commented out this line because it was causing issues with Internal VLD.
+ // TODO: Check why it caused issues with Internal VLD
+ // throw new ReferenceError('child already exists');
}
if (child.parent instanceof DescriptorModel) {
throw new ReferenceError('child already has a parent');
static newInternalConnectionPointRef(model, parent) {
// note do not find children bc model is not an object it is a leaf-list primative and so the class manages it
- return new InternalConnectionPointRef(model, parent);
+ return findChildDescriptorModelAndUpdateModel(model, parent) || new InternalConnectionPointRef(model, parent);
}
/**
return _.pick(ref, ['member-vnf-index-ref', 'vnfd-id-ref', 'vnfd-connection-point-ref']);
}
},
+ 'internal-connection-point': {
+ serialize(ref) {
+ return _.pick(ref, ['id-ref']);
+ }
+ },
'constituent-vnfd': {
serialize(cvnfdModel) {
if(!cvnfdFields) cvnfdFields = DescriptorModelMetaFactory.getModelFieldNamesForType('nsd.constituent-vnfd');
* limitations under the License.
*
*/
-/**
- * Created by onvelocity on 11/23/15.
- */
'use strict';
-import Position from '../../graph/Position'
-import DescriptorModel from '../DescriptorModel'
-import DescriptorModelFactory from '../DescriptorModelFactory'
+import Position from '../../graph/Position';
+import DescriptorModel from '../DescriptorModel';
+import DescriptorModelFactory from '../DescriptorModelFactory';
+import InternalConnectionPointRef from './InternalConnectionPointRef';
export default class InternalConnectionPoint extends DescriptorModel {
return this.id;
}
+ get id() {
+ return this.model.id;
+ }
+
+ get name() {
+ return this.model.name
+ }
+
+ get idRef() {
+ return this.parent.idRef;
+ }
+
+ get cpNumber() {
+ return this.uiState.cpNumber;
+ }
+
+ set cpNumber(n) {
+ this.uiState.cpNumber = n;
+ }
+
toInternalConnectionPointRef() {
- return DescriptorModelFactory.newInternalConnectionPointRef(this.id);
+ const ref = new InternalConnectionPointRef({});
+ ref.idRef = this.id;
+ // ref.cpNumber = this.cpNumber;
+ return ref;
}
canConnectTo(obj) {
* limitations under the License.
*
*/
-/**
- * Created by onvelocity on 11/23/15.
- */
'use strict';
export default class InternalConnectionPointRef extends DescriptorModel {
static get type() {
- return 'internal-connection-point-ref';
+ return 'internal-connection-point';
}
static get className() {
}
constructor(m, parent) {
- super(!m || typeof m === 'string' ? {id: m, isLeaf: true} : m, parent);
+ super(m, parent);
this.uid = this.id;
this.type = InternalConnectionPointRef.type;
this.uiState['qualified-type'] = InternalConnectionPointRef.qualifiedType;
this.className = InternalConnectionPointRef.className;
}
- toString() {
- return this.valueOf();
+ get key() {
+ return this.model['id-ref'];
}
- remove() {
- return this.parent.removeInternalConnectionPointRefForId(this.id);
+ get idRef() {
+ return this.model['id-ref'];
}
- valueOf() {
- return this.id;
+ set idRef(id) {
+ return this.model['id-ref'] = id;
+ }
+
+ get cpNumber() {
+ return this.uiState.cpNumber;
+ }
+
+ set cpNumber(n) {
+ this.uiState.cpNumber = n;
+ }
+
+ remove() {
+ return this.parent.removeInternalConnectionPointRefForId(this.idRef);
}
}
* limitations under the License.
*
*/
-/**
- * Created by onvelocity on 11/23/15.
- */
'use strict';
import DescriptorModel from '../DescriptorModel'
import DescriptorModelFactory from '../DescriptorModelFactory'
+import DescriptorModelMetaFactory from '../DescriptorModelMetaFactory'
export default class InternalVirtualLink extends DescriptorModel {
}
get connection() {
- const list = this.model['internal-connection-point-ref'] || (this.model['internal-connection-point-ref'] = []);
- return list.map(d => DescriptorModelFactory.newInternalConnectionPointRef(d, this));
+ if (!this.model['internal-connection-point']) {
+ this.model['internal-connection-point'] = [];
+ }
+ return this.model['internal-connection-point'].map(d => DescriptorModelFactory.newInternalConnectionPointRef(d, this));
}
set connection(connections) {
- return this.updateModelList('internal-connection-point-ref', connections, DescriptorModelFactory.InternalConnectionPointRef);
+ return this.updateModelList('internal-connection-point', connections, DescriptorModelFactory.InternalConnectionPointRef);
+ }
+
+ createInternalConnectionPoint(model) {
+ model = model || DescriptorModelMetaFactory.createModelInstanceForType('vnfd.internal-vld.internal-connection-point');
+ return this.connection = DescriptorModelFactory.newInternalConnectionPointRef(model, this);
+ }
+
+ removeInternalConnectionPointRefForIdRefKey(cpRefKey) {
+ const child = this.connection.filter(d => d.key === cpRefKey)[0];
+ return this.removeModelListItem('connection', child);
}
addConnectionPoint(icp) {
- icp.model['internal-vld-ref'] = this.id;
this.parent.removeAnyConnectionsForConnector(icp);
- this.connection = icp.toInternalConnectionPointRef();
+ const icpRef = icp.toInternalConnectionPointRef();
+ // this.connection = icp.toInternalConnectionPointRef();
+ this.connection = this.connection.concat(icpRef);
}
- removeInternalConnectionPointRefForId(id) {
- return this.connection = this.connection.filter(d => d.id !== id).map(d => d.id);
+ removeInternalConnectionPointRefForId(idRef) {
+ // return this.connection = this.connection.filter(d => d.idRef !== idRef).map(d => d.idRef);
+ // KKTODO: Check if below works instead
+ return this.connection = this.connection.filter(d => d.idRef !== idRef).map(d => d.model);
}
remove() {
* limitations under the License.
*
*/
-/**
- * Created by onvelocity on 11/23/15.
- */
'use strict';
import Position from '../../graph/Position'
-import DescriptorModel from '../DescriptorModel'
import InternalConnectionPoint from './InternalConnectionPoint'
-import RspConnectionPointRef from './RspConnectionPointRef'
-import VnfdConnectionPointRef from './VnfdConnectionPointRef'
-import DescriptorModelFactory from '../DescriptorModelFactory'
+
/**
- * A VirtualNetworkFunctionConnectionPoint is always a child of a VNFD. We use it to build VnfdConnectionPointRef instances. So convenience
+ * A VirtualDeploymentUnitInternalConnectionPoint is always a child of a VDU.
+ * We use it to build internal-connection-point.id-ref instances. So convenience
* methods are add to access the fields needed to do that.
*/
export default class VirtualDeploymentUnitInternalConnectionPoint extends InternalConnectionPoint {
* limitations under the License.
*
*/
-/**
- * Created by onvelocity on 11/23/15.
- */
'use strict';
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
list.push(<div key={i} className={"component"}><h2 style={{flex: '0 1 auto', justifyContent: 'center', alignSelf: 'center', display: displayTitle, padding: '0.5rem'}}>{title}</h2><div className="componentWrapper">{this.props.component_list[i].component}</div></div>);
}
}
-
return (
<div className={list.length > 1 ? '' : 'hideButtons'}>
<Slider {...settings}>
isOpenMano(props.ro) ?
dataCentersHTML(
props.dataCenters[props.ro.name],
- props.vnfFn.updateSelectedDataCenter.bind(null, v['member-vnf-index']))
+ props.vnfFn.updateSelectedDataCenter.bind(null, v['member-vnf-index']), true)
: null
}
{
{vlds && vlds.map(function(v, i) {
let currentType = v.type;
let isVIM = (currentType == 'vim-network-name');
- let isUnknown = (currentType == 'unknown') || ((currentType != 'vim-network-name') && (currentType != 'ip-profile-ref'));
+ let isUnknown = (currentType == 'none') || ((currentType != 'vim-network-name') && (currentType != 'ip-profile-ref'));
return (
<div key={self.props.nsd.id + '-' + i} className="inputControls">
<h4 className="inputControls-title">VLD: {v['short-name'] ? v['short-name'] : v['name']}</h4>
+ <label><span>Specify VLD Parameters</span></label>
<div className="inputControls-radioGroup">
<label className="inputControls-radio" style={{display: ipProfileList ? 'flex' : 'none'}}>
<input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={!isVIM && !isUnknown} value='ip-profile-ref' />
VIM Network Name
</label>
<label className="inputControls-radio">
- <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isUnknown} value='unknown' />
- Unknown
+ <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isUnknown} value='none' />
+ None
</label>
</div>
{
onChange={props.ipProfileFn.updateProfile(j, 'security-group')}
value={ipl['security-group']}
/>
+ <TextInput
+ label="subnet prefix pool"
+ onChange={props.ipProfileFn.updateProfile(j, 'subnet-prefix-pool')}
+ value={ipl['subnet-prefix-pool']}
+ />
<label>
<div style={{display:'flex'}}>
DNS SERVERS <span onClick={props.dnsFn.addDNS(j)} className="addInput"><img src={imgAdd} />Add</span>
return (
<div key={k} style={{display:'flex'}}>
<TextInput
- onChange={props.ipProfileFn.updateProfile(j,k)}
- value={ipl['dns-server'][k]}
+ onChange={props.dnsFn.updateDNS(j,k)}
+ value={ipl['dns-server'][k].address}
/>
<span onClick={props.dnsFn.removeDNS(j,k)} className="removeInput">
<img src={imgRemove} />Remove</span>
function dhcpHTML(props, ipl, j){
return (<div>
<TextInput
- label="DCHP Start Address"
+ label="DHCP Start Address"
onChange={props.ipProfileFn.updateDHCP(j, 'start-address')}
value={ipl['dhcp-params'] && ipl['dhcp-params']['start-address']}
/>
<TextInput
- label="DCHP Count"
+ label="DHCP Count"
onChange={props.ipProfileFn.updateDHCP(j, 'count')}
value={ipl['dhcp-params'] && ipl['dhcp-params']['count']}
/>
}
usersHTML = (props) => {
let usersFn = props.usersFn;
+ let sshKeysList = props.sshKeysList;
let usersList = props.usersList && props.usersList.map(function(u, i) {
+ let sshKeysRef = u['ssh-authorized-key'];
return (
<div className="input_group input_group-users" key={i}>
<div className="inputControls">
<div style={{fontWeight: 'bold', display: 'flex'}}>USER <span onClick={usersFn.remove(i)} className="removeInput"><img src={imgRemove} />Remove</span></div>
<TextInput onChange={usersFn.update(i, 'name')} label="USERNAME" value={i.name} />
- <TextInput onChange={usersFn.update(i, 'gecos')} label="REAL NAME" value={i.gecos} />
- <TextInput onChange={usersFn.update(i, 'passwd')} type="password" label="PASSWORD" value={i.passwd} />
+ <TextInput onChange={usersFn.update(i, 'user-info')} label="REAL NAME" value={i.gecos} />
+ {
+ sshKeysRef.map(function(ref, j) {
+ let keyref = JSON.stringify(ref)
+ return (
+ <div key={keyref.name + '-' + i + '-' + j} className="inputControls inputControls-sshkeys">
+ <label>
+ <div>
+ <SelectOption
+ label="Key Pair"
+ options={sshKeysList && sshKeysList.map(function(k) {
+ return {
+ label: k.name,
+ value: k
+ }
+ })}
+ ref="keyPairSelection"
+ initial={false}
+ defaultValue={ref}
+ onChange={usersFn.updateSSHkeyRef(i, j)}>
+ </SelectOption>
+ </div>
+ </label>
+ {
+ sshKeysRef.length > 0 ?
+ <label>
+ <span onClick={usersFn.updateSSHkeyRef(i, j, true)} className="removeInput">
+ <img src={imgRemove} />
+ Remove
+ </span>
+ </label>
+ : null
+ }
+
+ </div>
+ )
+ })
+ }
+ <div className="inputControls inputControls-sshkeys ">
+ <label style={{display: 'flex', 'flexDirection': 'row', 'alignItems': 'center'}}>
+ SSH KEY PAIR
+ <span onClick={usersFn.updateSSHkeyRef(i).bind(null, {target:{value: JSON.stringify(sshKeysList[0])}})} className="addInput">
+ <img src={imgAdd} />
+ ADD
+ </span>
+ </label>
+ </div>
</div>
</div>
)
<div className="configure-nsd_section">
<h3 className="launchpadCard_title">USERS</h3>
{usersList}
- <div className="inputControls inputControls-sshkeys ">
- <span onClick={usersFn.add} className="addInput">
- <img src={imgAdd} onClick={usersFn.add} />
+ <div className="inputControls inputControls-sshkeys inputControls-addUser ">
+ <span onClick={usersFn.add(sshKeysList)} className="addInput">
+ <img src={imgAdd} />
ADD USER
</span>
</div>
});
return CloudAccountOptions;
}
-function dataCentersHTML(dataCenters, onChange) {
+function dataCentersHTML(dataCenters, onChange, initial) {
//Build DataCenter options
//Relook at this, why is it an object?
let DataCenterOptions = [];
if (dataCenters && dataCenters.length > 0) {
return (
<label>Select Data Center
- <SelectOption options={DataCenterOptions} onChange={onChange} />
+ <SelectOption initial={!!initial} options={DataCenterOptions} onChange={onChange} />
</label>
)
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
-ms-flex: 0 1;
flex: 0 1;
}
+ .inputControls-sshkeys {
+ margin-bottom:1rem;
+ padding-top:0;
+ -ms-flex-align: end;
+ align-items: flex-end;
+ > label {
+ width:auto;
+ &:nth-child(2) {
+ margin-bottom: 1.25rem;
+ }
+ }
+ }
}
button {
/*remove button*/
display:-ms-flexbox;
display:flex;
}
+ &-addUser {
+ margin-top:1rem;
+ .addInput {
+ margin-left:0;
+ font-size:1rem;
+ >span {
+ color: #5b5b5b;
+ }
+ }
+ }
}
.addInput, .removeInput {
display:-ms-flexbox;
if(v['vim-network-name']) {
v.type = 'vim-network-name';
} else {
- v.type = 'unknown';
+ v.type = 'none';
}
}
return v;
} else {
delete vld[i]['dns-server'];
}
- if(type == 'unknown') {
+ if(type == 'none') {
delete vld[i]['ip-profile-ref'];
delete vld[i]['vim-network-name'];
}
}
//Removing DCHP property on disable to allow instantiation
if(!value) {
- delete self.ipProfiles[i]['ip-profile-params']['dhcp-params'];
+ self.ipProfiles[i]['ip-profile-params']['dhcp-params'] = {
+ enabled: false
+ };
} else {
self.ipProfiles[i]['ip-profile-params']['dhcp-params'][property] = value;
}
let self = this;
return function(e) {
if(self.ipProfiles[i]['ip-profile-params']['dns-server']) {
- self.ipProfiles[i]['ip-profile-params']['dns-server'].unshift('')
+ self.ipProfiles[i]['ip-profile-params']['dns-server'].unshift({})
} else {
- self.ipProfiles[i]['ip-profile-params']['dns-server'] = [''];
+ self.ipProfiles[i]['ip-profile-params']['dns-server'] = [{}];
}
self.setState({ipProfiles:self.ipProfiles});
}
self.setState({ipProfiles:self.ipProfiles});
}
+ },
+ updateDNS: (i, k) => {
+ let self = this;
+ return function(e) {
+ let value = e.target.value;
+ self.ipProfiles[i]['ip-profile-params']['dns-server'][k].address = value;
+ self.setState({ipProfiles:self.ipProfiles});
+ }
}
}
}
usersFn = () => {
let self = this;
return {
- add: function() {
- console.log('adding user')
- let newUser = {
- name: '',
- gecos: '',
- passwd: ''
+ add: function(sshKeysList) {
+ return function(e) {
+ let newUser = {
+ name: '',
+ 'user-info': '',
+ 'ssh-authorized-key': [sshKeysList[0].name]
+ }
+ let usersList = self.usersList;
+ usersList.push(newUser);
+ self.setState({
+ usersList: usersList
+ })
}
- let usersList = self.usersList;
- usersList.push(newUser);
- self.setState({
- usersList: usersList
- })
},
remove: function(i) {
return function() {
usersList: self.usersList
})
}
+ },
+ updateSSHkeyRef: function(i, j, remove){
+ return function(e) {
+ let usersList = _.cloneDeep(self.usersList)
+ let keys = usersList[i]['ssh-authorized-key'];
+ if(!remove) {
+ let keyRef = JSON.parse(e.target.value).name;
+ if(!isNaN(j)) {
+ keys.splice(j, 1);
+ }
+ keys.push(keyRef);
+ } else {
+ keys.splice(j, 1);
+ }
+ usersList[i]['ssh-authorized-key'] = keys;
+ self.setState({
+ usersList: usersList
+ })
+ }
}
}
}
nsdPayload['vnf-placement-groups'] && delete nsdPayload['vnf-placement-groups'];
nsdPayload.vld = this.state.vld;
nsdPayload.vld && nsdPayload.vld.map(function(v){
- delete v['unknown'];
+ delete v['none'];
delete v.type;
})
}
"nsd": nsdPayload
}
- if (this.state.ro['account-type'] == 'openmano') {
+ if (this.state.ro && this.state.ro['account-type'] == 'openmano') {
payload['om-datacenter'] = this.state.dataCenterID;
} else {
payload["cloud-account"] = this.state.selectedCloudAccount.name;
return {'key-pair-ref': JSON.parse(k).name};
});
//Add Users
- payload['user'] = this.state.usersList;
+ payload['user'] = addKeyPairRefToUsers(this.state.usersList);
// console.log(payload)
this.launchNSR({
'nsr': [payload]
}
+function addKeyPairRefToUsers(list) {
+ return list.map(function(u) {
+ return {
+ name: u.name,
+ 'user-info': u['user-info'],
+ 'ssh-authorized-key': u['ssh-authorized-key'].map(function(k) {
+ return {
+ 'key-pair-ref' : k
+ }
+ })
+ }
+ })
+}
function getMockSLA(id) {
console.log('Getting mock SLA Data for id: ' + id);
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
@import '../node_modules/open-iconic/font/css/open-iconic.css';
.app-body {
+ display:-ms-flexbox;
display:flex;
- flex-direction:column;
+ -ms-flex-direction:column;
+ flex-direction:column;
display: flex;
flex-direction: column;
- align-items: stretch;
+ -ms-flex-align: stretch;
+ align-items: stretch;
height: 100%;
}
color: $gray-darkest;
}
.lpReactDashboard {
+ display:-ms-flexbox;
display:flex;
height:100%;
.app-body {
> header {
- flex: 0 1 auto;
- flex-shrink: 0;
+ -ms-flex: 0 1 auto;
+ flex: 0 1 auto;
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
}
}
}
.lp-react-launch {
+ display: -ms-flexbox;
display: flex;
}
.app-body.create-fleet {
}
.baseGridCell {
- align-items: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -ms-flexbox;
display: flex;
- flex: 0 0 auto;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
min-height: 30px;
overflow: hidden;
padding-left: 2px;
}
.lp_dashboard {
+ display: -ms-flexbox;
display: flex;
- flex: 1;
- flex-direction: row;
+ -ms-flex: 1;
+ flex: 1;
+ -ms-flex-direction: row;
+ flex-direction: row;
height: 100%;
/* Network service list styles */
.leftMinimizedNsListPanel {
+ display: -ms-flexbox;
display: flex;
- flex: 1 100%;
+ -ms-flex: 1 100%;
+ flex: 1 100%;
height: auto;
max-width: 30px;
min-width: 30px;
background-color: white;
display:block;
h3 {
- // vertical | horizontal
- // top | horizonal | bottom
- // top right bottom left
+ /* vertical | horizontal*/
+ /* top | horizonal | bottom*/
+ /* top right bottom left*/
padding: 1.5rem 0;
color: white;
}
.nsListPanel {
+ display: -ms-flexbox;
display: flex;
- flex: 1 100%;
+ -ms-flex: 0 1;
+ flex: 0 1;
height: auto;
- max-width: 500px;
- min-width: 500px;
+ width: auto;
+ /* max-width: 500px;*/
+ /* min-width: 500px;*/
header {
background-color: white;
}
&-body {
- flex-flow: col wrap;
+ -ms-flex-flow: col wrap;
+ flex-flow: col wrap;
}
}
top:1.5rem;
right:0.5rem;
cursor:pointer;
+ display:-ms-flexbox;
display:flex;
&:before {
}
.nsListPanelToolbar {
background-color: $gray;
+ display: -ms-flexbox;
display: flex;
- flex: 0 0 auto;
- flex-direction: row;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ -ms-flex-direction: row;
+ flex-direction: row;
padding-left: 1rem;
.button {
cursor: pointer;
+ display: -ms-flexbox;
display: flex;
- //flex: 0;
+ /*flex: 0;*/
margin: 4px;
margin: 0.5rem;
img {
}
}
.nsList {
+ display: -ms-flexbox;
display: flex;
- flex: 1;
- flex-direction: column;
+ -ms-flex: 1;
+ flex: 1;
+ -ms-flex-direction: column;
+ flex-direction: column;
overflow: auto;
padding-left: 0;
padding-right: 0;
&-body {
- overflow-y: scroll;
+ overflow-y: auto;
+ overflow-x: hidden;
}
}
.nsListItemRow {
+ display: -ms-flexbox;
display: flex;
- flex-direction: row;
+ -ms-flex-direction: row;
+ flex-direction: row;
}
.cellValue {
overflow: hidden;
background-color: $gray;
border-top: 1px solid $gray-lightest;
border-bottom: 1px solid $gray-lightest;
+ display: -ms-flexbox;
display: flex;
- flex: 0 0 auto;
- flex-direction: row;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ -ms-flex-direction: row;
+ flex-direction: row;
}
.nsListItemField {
@extend .baseGridCell;
.actionButton {
cursor: pointer;
- // margin-top is a hack to fix the top of the glyph from
- // being chopped off
+ /* margin-top is a hack to fix the top of the glyph from*/
+ /* being chopped off*/
margin-top: 5px;
}
/* Network service detail card styles */
.nsCardPanel {
- //border: 1px solid black;
+ /*border: 1px solid black;*/
+ display: -ms-flexbox;
display: flex;
- flex: 1 1 auto;
- flex-wrap: nowrap;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ -ms-flex-wrap: nowrap;
+ flex-wrap: nowrap;
height: auto;
header {
background-color: white;
}
&-body {
background-color: $gray;
+ display: -ms-flexbox;
display: flex;
- flex: 1;
- flex-direction: row;
+ -ms-flex: 1;
+ flex: 1;
+ -ms-flex-direction: row;
+ flex-direction: row;
min-width: 0;
min-height: 0;
overflow-y: auto;
/* Angular wrapping */
lp-react-dashboard {
+ display:-ms-flexbox;
display:flex;
}
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
}
ret.push(html)
}
- return ret.sort(function(a, b){
- return (a.title > b.title) ? -1 : 1;
- });
+ return ret.sort(function(a,b) {
+ var titleA = a.title && a.title.toUpperCase();
+ var titleB = b.title && b.title.toUpperCase();
+ return (titleA < titleB) ? -1 : (titleA > titleB) ? 1 : 0;
+ });
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
<div className="scrollContainer">
{
//Sort for recent on top
- this.props.jobData.sort(function(a,b){
+ this.props.jobData
+ .sort(function(a,b){
return parseInt(b['job-id']) - parseInt(a['job-id']);
- }).map(function(job){
+ })
+ .map(function(job){
//Return only vnfr configs
if(job["triggered-by"] == 'vnf-primitive') {
return job.vnfr.map(function(v){
//That match the currently selected job id
if(v.id == cardData.id) {
return v.primitive.map(function(p, i) {
- return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={i} {...p} />
+ return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={ob['job-id'] + '-' + i} {...p} />
})
}
})
<div className="scrollContainer">
{sortedJobs.map(function(job, i){
if(job["triggered-by"] == 'ns-primitive') {
- return <JobListCard type="nsr" job-id={job['job-id']} cardData={cardData} key={i} {...job} />
+ return <JobListCard type="nsr" job-id={job['job-id']} cardData={cardData} key={job['job-id'] + '-' + 'nsr'} {...job} />
}
})
.concat(sortedJobs.map(function(job) {
if(!job.hasOwnProperty('job-name') && (job["triggered-by"] == 'ns-primitive')) {
- return job.vnfr.map(function(v){
+ return job.vnfr.map(function(v, h){
//That match the currently selected job id
if(v.id == cardData.id) {
return v.primitive.map(function(p, i) {
- return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={i} {...p} />
+ return <JobListCard type="vnfr" job-id={job['job-id']} cardData={cardData} key={ob['job-id'] + '-' + 'vnfr' + '-' + h} {...p} />
})
}
})
let nfviMetrics = <LpCardNfviMetrics data={cardData["nfvi-metrics"]} />;
metricsAndParams.push(<div className="monitoringParams" key="mp">
- {components.sort().map(function(c, k) {
+ {components.map(function(c, k) {
return <div key={k} className="mpSlide">{c.title}{c.component}</div>
})}
</div>)
if (consoleUrlsComponent) {
let consoleUrlsTabTitle = '';
consoleUrlsTabTitle = 'VDU Console Links';
-
+
tabList.push(
<Tab key={cardData.id + '-cp'}>{consoleUrlsTabTitle}</Tab>
);
let parameterList = [];
const filterAndAddByValue = (paramObj) => {
+ let nameValuePair = null;
+
if (paramObj['value'] != undefined) {
- parameterList.push({
+ nameValuePair = {
name: paramObj.name,
value: paramObj.value
- });
+ };
+ } else if (paramObj['default-value'] != undefined) {
+ nameValuePair = {
+ name: paramObj.name,
+ value: paramObj['default-value']
+ }
}
+ if (nameValuePair) {
+ parameterList.push(nameValuePair);
+ }
+
return paramObj['value'] != undefined;
}
let vld = _.cloneDeep(this.vld);
this.vldInitParamsTypes.map((vldInitParamType) => {
if (currentVLDInitParamsType == vldInitParamType) {
- vld[currentVLDInitParamsType] = e.target.value;
+ let value = e.target.nodeName == "SELECT" ? JSON.parse(e.target.value) : e.target.value;
+ vld[currentVLDInitParamsType] = value;
} else {
vld[vldInitParamType] && delete vld[vldInitParamType];
}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* limitations under the License.
*
*/
+'use strict';
var Promise = require('bluebird');
var utils = require('../../../framework/core/api_utils/utils.js');
var request = utils.request;
var constants = require('../../../framework/core/api_utils/constants.js');
var _ = require('lodash');
-var APIVersion = '/v1';
+var APIVersion = '/v2';
var transforms = require('./transforms.js');
var foreverOn = true;
} else {
var data = JSON.stringify(response.body);
}
- return resolve_with_delay(resolve, {
+ return resolve({
statusCode: response.statusCode,
data: data
- }, 0);
+ });
};
};
}
// Do nothing to test delay in response
var encoder = new transforms.LoggingConfigEncoder();
var data = encoder.encode(req.body);
- //console.log("Aggregate.set. encoded data=");
- //console.log(data);
+ // console.log("Aggregate.set. encoded data=");
+ // console.log(data);
// dumpLoggingConfig(data);
-
- return handlePutRequest(req, APIVersion + '/api/config/logging', data);
+ let setData = {
+ 'rwlog-mgmt:logging' : data
+ }
+ return handlePutRequest(req, APIVersion + '/api/config/logging', setData);
// if (this.mockResponse['set']) {
// return handleMockResponse(req, true, 201, data, delay=100);
// }
}
+// NOTE: In rel_4.3 we are going to affect syslog sink category by default
+
+Config.setDefaultSyslogSeverity = function(req) {
+ // TODO: verify there is one key at root of data: 'default-severity'
+ // OR just filter on the request body
+ return handlePutRequest(req, APIVersion + '/api/config/logging/sink/syslog');
+}
+
+Config.deleteDefaultSyslogSeverity = function(req) {
+ // TODO: verify there is one key at root of data: 'default-severity'
+ // OR just filter on the request body
+ var Categories = req.params.nulledCategories.split(',');
+ var promises = [];
+ return new Promise(function(resolve, reject) {
+ promises.concat(Categories.map(function(categoryName) {
+ return handleDeleteRequest(req, APIVersion + '/api/config/logging/sink/syslog/filter/category/' + categoryName);
+ }));
+ return Promise.all(promises).then(
+ function(data) {
+ resolve({statusCode: data[0].statusCode, data: data[0].data});
+ },
+ function(data) {
+ reject({statusCode: data[0].statusCode, data: data[0].data});
+ }
+ )
+ });
+}
+
/*
get body of forms
Config.setAllowDuplicateEvents = function(req) {
// TODO: verify there is one key at root of data: 'default-severity'
// OR just filter on the request body
-
- if (req.body.hasOwnProperty('allowDuplicateEvents') &&
- typeof req.body.allowDuplicateEvents == 'boolean') {
- if (req.body.allowDuplicateEvents) {
- return handlePutRequest(req, APIVersion + '/api/config/logging/allow', {
+console.log(req.body)
+ if (req.body.hasOwnProperty('allowDuplicateEvents')) {
+ if (req.body.allowDuplicateEvents.toUpperCase() == "TRUE") {
+ return handlePutRequest(req, '/api/config/logging/allow', {
"duplicate": "events"
});
} else { // false, remove entry from logging config
- return handleDeleteRequest(req, APIVersion + '/api/config/logging/allow/duplicate');
+ return handleDeleteRequest(req, '/api/config/logging/allow/duplicate');
}
} else {
return handleReject(statusCode=400,
// Operational calls
Operational.get = function(req) {
+ var APIVersion = '/v1'
return handleGetRequest(req, APIVersion + '/api/operational/logging?deep',
transformLoggingRootResponseCallback
);
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* or absence of the { "allow": { "duplicate": "events" }} key/value hierarchy
*/
LoggingConfigEncoder.prototype.allow = function(data) {
- if (data.allowDuplicateEvents) {
+ if (data.allowDuplicateEvents && data.allowDuplicateEvents.toUpperCase() == "TRUE") {
return { duplicate: "events" };
} else {
return null;
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
endpoint: '/api/config/default-severity',
apiHandler: loggingAPI['config'].deleteDefaultSeverity
},
+ {
+ method: 'PUT',
+ endpoint: '/api/config/default-syslog-severity',
+ apiHandler: loggingAPI['config'].setDefaultSyslogSeverity
+ },
+ {
+ method: 'DELETE',
+ endpoint: '/api/config/default-syslog-severity/:nulledCategories',
+ apiHandler: loggingAPI['config'].deleteDefaultSyslogSeverity
+ },
{
method: 'PUT',
endpoint: '/api/config/allow-duplicate-events',
generateRows(defaultSeverities, severityOptions) {
let self = this;
return defaultSeverities.map(function(catsev) {
+ // let dropList = (<DropList options={severityOptions}
+ // selectedOption={catsev.severity}
+ // onChange={self.onChangeSeverity(catsev.category)} />);
let dropList = (<DropList options={severityOptions}
selectedOption={catsev.severity}
- onChange={self.onChangeSeverity(catsev.category)} />);
- return [catsev.category, dropList];
+ onChange={self.onChangeSyslogSeverity(catsev.name)} />);
+ return [catsev.name, dropList];
});
}
- onChangeSeverity (category) {
+ // onChangeSeverity (category) {
+ // return function(e) {
+ // LoggingStore.updateCategoryDefaultSeverity({
+ // category: category,
+ // severity: e
+ // });
+ // }
+ // }
+
+ onChangeSyslogSeverity (name) {
return function(e) {
- LoggingStore.updateCategoryDefaultSeverity({
- category: category,
+ LoggingStore.updateCategoryDefaultSyslogSeverity({
+ name: name,
severity: e
});
}
CategorySeverityGrid.defaultProps = {
cellLabels: [
- 'Category', 'Severity'
+ 'Name', 'Severity'
],
columnClasses: [
'category', 'severity'
return (
<DashboardCard className="defaultCategorySeverityPanel"
showHeader={true}
- title="Default Category Severity">
+ title="Syslog Category Severity">
<CategorySeverityGrid defaultSeverities={defaultSeverities}
severityOptions={severities}/>
</DashboardCard>
isLoading: true
});
LoggingStore.updateLoggingConfig(
- this.collectNulledCategories(
+ /* this.collectNulledCategories(
this.state.initialLoggingConfig,
this.state.loggingConfig),
- this.removeCategoryNulls(
- this.state.loggingConfig
- )
- );
+ this.removeCategoryNulls(
+ this.state.loggingConfig */
+ this.state.nulledCategories,
+ this.cleanupConfig(
+ this.state.loggingConfig
+ )
+ )
} else {
console.log("LoggingGeneral.handleSave failed validation");
}
this.context.router.push({pathname: ''});
}
- removeCategoryNulls(config) {
+ // removeCategoryNulls(config) {
+ // let cleanConfig = _.cloneDeep(config);
+ // let cleanSeverities = [];
+ // config.defaultSeverities.map(function(d) {
+ // if (d.severity) {
+ // cleanSeverities.push(d);
+ // }
+ // });
+ // cleanConfig.defaultSeverities = cleanSeverities;
+ // return cleanConfig;
+ // }
+ cleanupConfig(config) {
let cleanConfig = _.cloneDeep(config);
let cleanSeverities = [];
- config.defaultSeverities.map(function(d) {
- if (d.severity) {
- cleanSeverities.push(d);
+ cleanConfig.defaultSeverities && cleanConfig.defaultSeverities.map((defSev) => {
+ if (defSev.severity) {
+ cleanSeverities.push(defSev);
}
});
cleanConfig.defaultSeverities = cleanSeverities;
+
return cleanConfig;
}
- collectNulledCategories(oldCat, newCat) {
- let nulledCategories = [];
- let newSeverities = newCat.defaultSeverities;
- let oldSeverities = oldCat.defaultSeverities;
- newSeverities.map(function(c, i) {
- if(!c.severity) {
- if(oldSeverities[i].severity) {
- //verify that categories are the same
- if(oldSeverities[i].category == c.category) {
- nulledCategories.push({category: c.category})
- }
- }
- }
- });
- return nulledCategories;
- }
+ // collectNulledCategories(oldCat, newCat) {
+ // let nulledCategories = [];
+ // let newSeverities = newCat.defaultSeverities;
+ // let oldSeverities = oldCat.defaultSeverities;
+ // newSeverities.map(function(c, i) {
+ // if(!c.severity) {
+ // if(oldSeverities[i].severity) {
+ // //verify that categories are the same
+ // if(oldSeverities[i].category == c.category) {
+ // nulledCategories.push({category: c.category})
+ // }
+ // }
+ // }
+ // });
+ // return nulledCategories;
+ // }
validateData() {
function isEventIdValid(eventID) {
let syslogViewerURL = this.state.loggingConfig.syslogviewer;
let defaultSeverities = this.state.loggingConfig.defaultSeverities;
+ // NOTE: There are modifications to original code here
+ // for RIFT-14856 so that default severities map to syslog sink
+
+ // Find first syslog sink with (WTF - no type on sinks!) name syslog.
+ let syslogSink = this.state.loggingConfig.sinks && _.find(this.state.loggingConfig.sinks, {
+ name: 'syslog'
+ });
+ let defaultSyslogSeverities = [];
+
+ this.state.loggingConfig && this.state.loggingConfig.defaultSeverities && this.state.loggingConfig.defaultSeverities.map((defaultSeverity) => {
+ // Mapping between default categories and names inside a sink
+ let syslogFilterCategory = (syslogSink.filter && syslogSink.filter.category && _.find(syslogSink.filter.category, {
+ name: defaultSeverity.category
+ })) || {
+ name: defaultSeverity.category,
+ severity: null
+ };
+ defaultSyslogSeverities.push(syslogFilterCategory);
+ });
let severities = this.state.loggingConfig.severities;
let allowDuplicateEvents = this.state.loggingConfig.allowDuplicateEvents;
let denyEventIDs = this.state.loggingConfig.denyEventIDs;
{errorMessage}
<ScreenLoader show={this.state.isLoading}/>
<div className="panelContainer">
- <DefaultCategorySeverityPanel defaultSeverities={defaultSeverities}
+ {/*<DefaultCategorySeverityPanel defaultSeverities={defaultSeverities}
+ severities={severities}
+ />*/}
+ <DefaultCategorySeverityPanel defaultSeverities={defaultSyslogSeverities}
severities={severities}
/>
<LoggingEventsPanel allowDuplicateEvents={allowDuplicateEvents}
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
return new Promise(function(resolve, reject) {
let promises = [];
let remove = null;
- let change = $.ajax({
+ if(loggingConfig.hasOwnProperty('allowDuplicateEvents')) {
+ promises.push($.ajax({
+ url: apiUrl('api/config/allow-duplicate-events'),
+ type: 'PUT',
+ beforeSend: Utils.addAuthorizationStub,
+ data: {
+ allowDuplicateEvents: loggingConfig.allowDuplicateEvents
+ },
+ success: function(data) {
+ resolve(data);
+ },
+ error: function(error) {
+ console.log("There was an error updating the logging config data",
+ error);
+ reject(error);
+ }
+ }))
+ }
+ // if(nulledCategories.length > 0) {
+ // remove = $.ajax({
+ // // url: apiUrl('api/config/default-severity'),
+ // url: apiUrl('api/config/default-syslog-severity/' + nulledCategories.join(',')),
+ // type: 'DELETE',
+ // beforeSend: Utils.addAuthorizationStub,
+ // success: function(data) {
+ // resolve(data);
+ // },
+ // error: function(error) {
+ // console.log("There was an error updating the logging config data",
+ // error);
+ // reject(error);
+ // }
+ // });
+ // promises.push(remove);
+ // }
+ Promise.all(promises).then(function(data) {
+ return $.ajax({
url: apiUrl('api/aggregate'),
type: 'PUT',
beforeSend: Utils.addAuthorizationStub,
reject(error);
}
});
- promises.push(change);
- if(nulledCategories.length > 0) {
- remove = $.ajax({
- url: apiUrl('api/config/default-severity'),
- type: 'DELETE',
- beforeSend: Utils.addAuthorizationStub,
- data: {
- 'default-severity' : nulledCategories
- },
- success: function(data) {
- resolve(data);
- },
- error: function(error) {
- console.log("There was an error updating the logging config data",
- error);
- reject(error);
- }
- });
- promises.push(remove);
- }
-
-
- Promise.all(promises).then(function(data){
+ }).then(function(data){
resolve(data)
}, function(){
reject(arguments)
/*
- *
+ *
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
this.loggingConfig = {};
// initialLoggingConfig is the saved state
this.initialLoggingConfig = {};
+ this.nulledCategories = [];
this.bindActions(LoggingActions);
this.registerAsync(LoggingSource);
this.exportPublicMethods({
updateCategoryDefaultSeverity: this.updateCategoryDefaultSeverity,
+ updateCategoryDefaultSyslogSeverity: this.updateCategoryDefaultSyslogSeverity,
updateAllowDuplicateEvents: this.updateAllowDuplicateEvents,
addDenyEvent: this.addDenyEvent,
updateDenyEvent: this.updateDenyEvent,
}
}
+ updateCategoryDefaultSyslogSeverity = (catsev) => {
+ console.log("LoggingStore.updateCategoryDefaultSyslogSeverity:", catsev);
+ // find the category (name) in the syslog sink
+
+ let self = this;
+ let loggingConfig = _.cloneDeep(this.loggingConfig);
+ let syslogSinkIndex = -1;
+ let nulledCategories = this.nulledCategories;
+
+ loggingConfig.sinks && loggingConfig.sinks.map((sink, sinkIndex) => {
+ if (sink.name == 'syslog') {
+ if (sink.filter) {
+ if (sink.filter.category) {
+ let catIndex = _.findIndex(sink.filter.category, {
+ name: catsev.name
+ });
+ if (catIndex != -1) {
+ // found it
+ if (catsev.severity == "") {
+ // blank was selected
+ nulledCategories.push(catsev.name);
+ this.setState({
+ nulledCategories: nulledCategories
+ });
+ // TODO/NOTE: Can't delete from model as sending a top-level payload with
+ // missing elements is not allowed!
+ // When backend supports it, in loggingSource change the order of operations
+ // // Delete first followed by save/put.
+ // _.remove(loggingConfig.sinks[sinkIndex].filter.category, {
+ // name: catsev.name
+ // });
+ } else {
+ sink.filter.category[catIndex] = catsev;
+ }
+ } else {
+ _.remove(nulledCategories, (v) => v == catsev.name);
+ this.setState({
+ nulledCategories: nulledCategories
+ });
+ sink.filter.category.push(catsev);
+ }
+ } else {
+ sink.filter.category = [];
+ sink.filter.category.push(catsev);
+ }
+ } else {
+ sink.filter = {};
+ sink.filter.category = [];
+ sink.filter.category.push(catsev);
+ }
+ }
+ });
+
+ this.setState({
+ loggingConfig: loggingConfig
+ });
+ }
+
updateAllowDuplicateEvents = (allowFlag) => {
console.log("LoggingStore.updateAllowDuplicateEvents called. allowFlag=", allowFlag);
const loggingConfig = this.loggingConfig;