3 * Copyright 2016 RIFT.IO Inc
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 import NetworkServiceActions
from './launchNetworkServiceActions.js';
19 import NetworkServiceSource
from './launchNetworkServiceSource.js';
20 import GUID
from 'utils/guid.js';
21 import AppHeaderActions
from 'widgets/header/headerActions.js';
22 import Alt
from '../alt';
23 import _cloneDeep
from 'lodash/cloneDeep';
24 import _find
from 'lodash/find';
25 import _merge
from 'lodash/merge';
27 class LaunchNetworkServiceStore
{
37 this.sshKeysList
= [];
39 this.sla_parameters
= [];
41 this.selectedNSD
= {};
42 this.dataCenters
= [];
43 this.isLoading
= false;
44 this.hasConfigureNSD
= false;
45 this.hasConfigureVNFD
= false;
46 this['input-parameters'] = [];
47 this.displayPlacementGroups
= true;
48 this.bindActions(NetworkServiceActions
);
49 this.nsdConfiguration
= {
53 /*Collection of vnf state containting cloud account and datacenter info.
57 this.configAgentAccounts
= [];
59 this.isPreviewing
= false;
60 this.isOpenMano
= false;
62 this.displayVIMAccounts
= false;
63 this.resourceOrchestrators
= [{
65 'ro-account-type': 'openmano'
67 this.selectedResourceOrchestrator
= this.resourceOrchestrators
[0];
68 this.dataCenterID
= null;
69 this.vnfDataCenters
= {};
70 this.registerAsync(NetworkServiceSource
);
71 this.exportPublicMethods({
72 getMockData
: getMockData
.bind(this),
73 getMockSLA
: getMockSLA
.bind(this),
74 saveNetworkServiceRecord
: this.saveNetworkServiceRecord
,
77 updateInputParam
: this.updateInputParam
,
78 resetView
: this.resetView
,
79 nameUpdated
: this.nameUpdated
,
81 descriptorSelected
: this.descriptorSelected
.bind(this),
82 deselectDescriptor
: this.deselectDescriptor
,
83 previewDescriptor
: this.previewDescriptor
,
85 ipProfileFn
: this.ipProfileFn
,
87 usersFn
: this.usersFn
,
94 console
.log('reseting state');
97 'input-parameter-xpath': null,
98 'ns-placement-groups': null,
99 'vnf-placement-groups':null
105 getCatalogSuccess(catalogs
) {
111 catalogs
.forEach(function(catalog
) {
112 switch (catalog
.type
) {
116 self
.descriptorSelected(catalog
.descriptors
[0])
118 console
.log('unable to select catalog')
129 nsd
[0].descriptors
.map(function(n
) {
133 nsd
, vnfd
, pnfd
, nsdDict
,
137 getConfigAgentSuccess(configAgentAccounts
) {
139 configAgentAccounts
: configAgentAccounts
142 getDataCentersSuccess(data
) {
143 let dataCenters
= data
;
146 dataCenters
: dataCenters
|| []
148 if (this.ro
&& this.ro
['account-type'] == 'openmano') {
149 newState
.dataCenterID
= dataCenters
[this.ro
.name
][0].uuid
151 this.setState(newState
)
153 getVDUSuccess(VNFD
) {
159 Alt
.actions
.global
.showScreenLoader
.defer();
163 console
.log('is Loading', this)
165 launchNSRSuccess(data
) {
166 console
.log('Launching Network Service')
167 let tokenizedHash
= window
.location
.hash
.split('/');
168 Alt
.actions
.global
.hideScreenLoader
.defer();
172 return window
.location
.hash
= 'launchpad/' + tokenizedHash
[2];
174 launchNSRError(data
) {
175 Alt
.actions
.global
.showNotification
.defer(data
);
176 Alt
.actions
.global
.hideScreenLoader
.defer();
181 getInstantiateSshKeySuccess
= (data
) => {
187 getResourceOrchestratorAccountsSuccess
= (data
) => {
189 Alt
.actions
.global
.hideScreenLoader
.defer();
192 resourceOrchestrators
: ROAccounts
.concat(data
).filter(function(r
){ return r
.name
!= "rift" }),
193 selectedResourceOrchestrator
: data
[0],
194 dataCenterID
: data
&& data
[0] && data
[0].datacenters
&& data
[0].datacenters
.datacenters
&& data
[0].datacenters
.datacenters
[0] && data
[0].datacenters
.datacenters
[0].name
,
195 dataCenterType
: data
&& data
[0] && data
[0].datacenters
&& data
[0].datacenters
.datacenters
&& data
[0].datacenters
.datacenters
[0] && data
[0].datacenters
.datacenters
[0]['datacenter-type'],
196 displayVIMAccounts
: false
199 getResourceOrchestratorError
= (data
) => {
200 console
.log('getResourceOrchestrator Error: ', data
)
203 nameUpdated
= (e
) => {
208 deselectDescriptor
= () => {
209 console
.log('deselecting')
216 descriptorSelected
= (data
) => {
221 selectedNSDid
: NSD
.id
,
222 vld
: NSD
&& NSD
.vld
&& NSD
.vld
.map(function(v
) {
223 //Adding a type for UI state management
224 //This is deleted before launch
225 if(v
['ip-profile-ref']) {
226 v
.type
= 'ip-profile-ref';
228 if(v
['vim-network-name']) {
229 v
.type
= 'vim-network-name';
236 ipProfiles
: NSD
['ip-profiles']
238 newState
.selectedNSD
= data
;
239 newState
['input-parameters'] = [];
240 newState
['vnf-input-parameter'] = [];
241 if (NSD
['input-parameter-xpath']) {
242 let vnfParameters
= [];
243 newState
.hasConfigureNSD
= true;
244 NSD
['input-parameter-xpath'].map(function(p
) {
245 if (isVNFDInputParameter(p
)) {
246 newState
.hasConfigureVNFD
= true;
247 vnfParameters
.push(p
);
249 newState
.hasConfigureNSD
= true;
250 newState
['input-parameters'].push(p
);
253 newState
['vnf-input-parameter'] = NSD
['constituent-vnfd'].map(function(vnf
) {
255 'name': vnf
['vnf-name'],
256 'member-vnf-index-ref': vnf
['member-vnf-index'],
257 'vnfd-id-ref': vnf
['vnfd-id-ref'],
258 'input-parameter':_cloneDeep(vnfParameters
)
262 newState
.hasConfigureNSD
= false;
263 newState
['input-parameter'] = null;
265 if(NSD
['ns-placement-groups'] && NSD
['ns-placement-groups'].length
> 0 ) {
266 newState
['ns-placement-groups'] = NSD
['ns-placement-groups'];
268 if(NSD
['vnf-placement-groups'] && NSD
['vnf-placement-groups'].length
> 0 ) {
269 newState
['vnf-placement-groups'] = NSD
['vnf-placement-groups'];
271 NSD
["constituent-vnfd"] && NSD
["constituent-vnfd"].map((v
) => {
272 VNFIDs
.push(v
["vnfd-id-ref"]);
274 this.getInstance().getVDU(VNFIDs
);
275 this.setState(newState
);
277 function isVNFDInputParameter(p
){
278 return p
.xpath
.match('vnfd-catalog');
281 previewDescriptor
= (data
) => {
290 updateInputParam
= (i
, value
) => {
291 let ip
= this['input-parameters'];
294 'input-parameters': ip
297 updateVnfInputParam
= (i
, j
, value
) => {
298 let ip
= this['vnf-input-parameter'];
299 ip
[i
]['input-parameter'][j
].value
= value
;
301 'vnf-input-parameter': ip
307 updateSelectedRoAccount
: (resourceOrchestrator
) => {
308 let nsd
= self
.nsd
[0];
310 selectedResourceOrchestrator
: JSON
.parse(JSON
.parse(resourceOrchestrator
.target
.value
))
312 // if no datacenters and ro is not rift-ro
313 if (!(newState
.selectedResourceOrchestrator
.datacenters
&& newState
.selectedResourceOrchestrator
.datacenters
.datacenters
) ) {
314 Alt
.actions
.global
.showNotification
.defer("No data centers configured in resource orchestrator");
316 newState
.dataCenterID
= newState
.selectedResourceOrchestrator
.datacenters
.datacenters
[0].name
;
317 newState
.dataCenterType
= newState
.selectedResourceOrchestrator
.datacenters
.datacenters
[0]['datacenter-type'];
318 newState
.displayPlacementGroups
= newState
.selectedResourceOrchestrator
.name
== "rift" ? true : false;
320 self
.setState(newState
);
322 updateSelectedDataCenter
: (dataCenter
) => {
323 let dataCenterID
= JSON
.parse(JSON
.parse(dataCenter
.target
.value
));
324 let dataCenterType
= _find(self
.selectedResourceOrchestrator
.datacenters
.datacenters
, {name
: dataCenterID
})
331 placementGroupUpdate
: (i
, k
, event
) => {
332 let value
= event
.target
.value
;
333 let pg
= self
['ns-placement-groups'];
336 'ns-placement-groups': pg
339 hostAggregateUpdate
: (pgi
, hai
, k
, event
) => {
340 let value
= event
.target
.value
;
341 let pg
= self
['ns-placement-groups'];
342 let ha
= pg
[pgi
]['host-aggregate'][hai
];
345 'ns-placement-groups': pg
348 addHostAggregate
: (pgi
) => {
349 let pg
= self
['ns-placement-groups'];
350 let ha
= pg
[pgi
]['host-aggregate'];
353 'ns-placement-groups': pg
356 removeHostAggregate
: (pgi
, hai
) => {
357 let pg
= self
['ns-placement-groups'];
358 let ha
= pg
[pgi
]['host-aggregate'];
361 'ns-placement-groups': pg
364 getNSDByID
: (id
) => {
372 placementGroupUpdate
: (i
, k
, event
) => {
373 let value
= event
.target
.value
;
374 let pg
= self
['vnf-placement-groups'];
377 'vnf-placement-groups': pg
380 hostAggregateUpdate
: (pgi
, hai
, k
, event
) => {
381 let value
= event
.target
.value
;
382 let pg
= self
['vnf-placement-groups'];
383 let ha
= pg
[pgi
]['host-aggregate'][hai
];
386 'vnf-placement-groups': pg
389 addHostAggregate
: (pgi
) => {
390 let pg
= self
['vnf-placement-groups'];
391 let ha
= pg
[pgi
]['host-aggregate'];
394 'vnf-placement-groups': pg
397 removeHostAggregate
: (pgi
, hai
) => {
398 let pg
= self
['vnf-placement-groups'];
399 let ha
= pg
[pgi
]['host-aggregate'];
402 'vnf-placement-groups': pg
405 updateSelectedConfigAgent
: (id
) => {
407 let configAgentRef
= JSON
.parse(e
.target
.value
);
408 let vnfDC
= self
.vnfDataCenters
;
413 vnfDC
[id
]['config-agent-account'] = configAgentRef
;
415 if(vnfDC
[id
].hasOwnProperty('datacenter')) {
416 delete vnfCA
[id
]['config-agent-account'];
422 vnfDataCenters
: vnfDC
426 updateSelectedDataCenter
: (id
, dataCenter
) => {
427 let vnfDC
= self
.vnfDataCenters
;
428 let dc
= JSON
.parse(JSON
.parse(dataCenter
.target
.value
));
432 vnfDC
[id
]['member-vnf-index-ref'];
434 vnfDC
[id
].datacenter
= dc
;
440 vnfDataCenters
: vnfDC
450 let type
= e
.target
.value
;
452 if (vld
[i
].hasOwnProperty('type')) {
453 delete vld
[i
][vld
[i
].type
]
457 if(type
== 'ip-profile-ref') {
458 let IPProfile
= self
.ipProfiles
;
459 vld
[i
][type
] = IPProfile
[0] && IPProfile
[0].name
;
460 delete vld
[i
]['vim-network-name'];
461 delete vld
[i
]['ipv4-nat-pool-name'];
463 delete vld
[i
]['dns-server'];
464 vld
[i
]['ipv4-nat-pool-name'] = self
.dataCenterID
467 delete vld
[i
]['ip-profile-ref'];
468 delete vld
[i
]['vim-network-name'];
469 delete vld
[i
]['ipv4-nat-pool-name'];
471 self
.setState({vld
:vld
});
474 updateValue
: (i
, type
) => {
476 // Select Option returns JSON values.
477 let value
= e
.target
.nodeName
== "SELECT" ? JSON
.parse(e
.target
.value
) : e
.target
.value
;
479 vld
[i
][type
] = value
;
480 self
.setState({vld
:vld
});
485 ipProfileFn
= () => {
488 updateProfile
: (i
, key
) => {
490 // Select Option returns JSON values.
491 let value
= e
.target
.nodeName
== "SELECT" ? JSON
.parse(e
.target
.value
) : e
.target
.value
;
492 self
.ipProfiles
[i
]['ip-profile-params'][key
] = value
;
495 // Don't send this key
496 delete self
.ipProfiles
[i
]['ip-profile-params'][key
];
499 self
.setState({ipProfiles
:self
.ipProfiles
});
502 updateVersion
: (i
) => {
504 // Select Option returns JSON values.
505 let value
= e
.target
.value
;
506 self
.ipProfiles
[i
]['ip-profile-params']['ip-version'] = value
;
507 self
.setState({ipProfiles
:self
.ipProfiles
});
510 updateDNS
: (i
, dnsIndex
) => {
512 // Select Option returns JSON values.
513 let value
= e
.target
.nodeName
== "SELECT" ? JSON
.parse(e
.target
.value
) : e
.target
.value
;
514 self
.ipProfiles
[i
]['ip-profile-params']['dns-server'][dnsIndex
] = value
;
515 self
.setState({ipProfiles
:self
.ipProfiles
});
518 updateDHCP
: (i
, property
) => {
520 let value
= e
.target
.value
;
521 //If value is meant to be boolean, convert it
522 if(value
== "true" || value
== "false") {
523 value
= JSON
.parse(value
);
525 if(!self
.ipProfiles
[i
]['ip-profile-params'].hasOwnProperty('dhcp-params')) {
526 self
.ipProfiles
[i
]['ip-profile-params']['dhcp-params'] = {
532 //Removing DCHP property on disable to allow instantiation
534 self
.ipProfiles
[i
]['ip-profile-params']['dhcp-params'] = {
538 self
.ipProfiles
[i
]['ip-profile-params']['dhcp-params'][property
] = value
;
540 self
.setState({ipProfiles
:self
.ipProfiles
});
551 if(self
.ipProfiles
[i
]['ip-profile-params']['dns-server']) {
552 self
.ipProfiles
[i
]['ip-profile-params']['dns-server'].unshift({})
554 self
.ipProfiles
[i
]['ip-profile-params']['dns-server'] = [{}];
557 self
.setState({ipProfiles
:self
.ipProfiles
});
560 removeDNS
: (i
, k
) => {
563 self
.ipProfiles
[i
]['ip-profile-params']['dns-server'].splice(k
, 1);
564 if(self
.ipProfiles
[i
]['ip-profile-params']['dns-server'].length
== 0) {
565 delete self
.ipProfiles
[i
]['ip-profile-params']['dns-server'];
567 self
.setState({ipProfiles
:self
.ipProfiles
});
570 updateDNS
: (i
, k
) => {
573 let value
= e
.target
.value
;
574 self
.ipProfiles
[i
]['ip-profile-params']['dns-server'][k
].address
= value
;
575 self
.setState({ipProfiles
:self
.ipProfiles
});
583 updateNewKeyRefSelection
: (e
) => {
585 newRefSelection
: e
.target
.value
588 updateKeyRef
: (refIndex
, remove
) => {
591 let sshKeysRef
= self
.sshKeysRef
;
593 // if(!e.target.value) {
594 // return Alt.actions.global.showError.defer('Please select a key pair');
596 if(!isNaN(refIndex
)){
597 sshKeysRef
.splice(refIndex
, 1);
598 sshKeysRef
.push(e
.target
.value
);
600 sshKeysRef
.push(e
.target
.value
);
604 sshKeysRef
.splice(refIndex
, 1);
607 sshKeysRef
: sshKeysRef
,
608 newRefSelection
: null
617 add: function(sshKeysList
) {
622 'ssh-authorized-key': [sshKeysList
[0].name
]
624 let usersList
= self
.usersList
;
625 usersList
.push(newUser
);
631 remove: function(i
) {
633 self
.usersList
.splice(i
, 1);
635 usersList
: self
.usersList
639 update: function(i
, key
) {
641 let value
= e
.target
.value
;
642 self
.usersList
[i
][key
] = value
;
644 usersList
: self
.usersList
648 updateSSHkeyRef: function(i
, j
, remove
){
650 let usersList
= _cloneDeep(self
.usersList
)
651 let keys
= usersList
[i
]['ssh-authorized-key'];
653 let keyRef
= JSON
.parse(e
.target
.value
).name
;
661 usersList
[i
]['ssh-authorized-key'] = keys
;
669 saveNetworkServiceRecord(name
, launch
) {
671 //input-parameter: [{uuid: < some_unique_name>, xpath: <same as you got from nsd>, value: <user_entered_value>}]
673 'input-parameter-xpath':[{
681 // Create a filtered NSD payload from the decorated one as RW.REST cannot handle extra parameters now
683 nsdPayload
= _cloneDeep(_find(this.state
.nsd
[0].descriptors
, {id
: this.state
.selectedNSDid
}));
685 if (nsdPayload
!= {}) {
686 nsdPayload
['meta'] && delete nsdPayload
['meta'];
687 nsdPayload
['constituent-vnfd'] && nsdPayload
['constituent-vnfd'].map((constituentVnfd
) => {
688 constituentVnfd
['vnf-name'] && delete constituentVnfd
['vnf-name'];
689 constituentVnfd
['name'] && delete constituentVnfd
['name'];
691 nsdPayload
['placement-groups'] && nsdPayload
['placement-groups'].map((placementGroup
) => {
692 placementGroup
['member-vnfd'] && placementGroup
['member-vnfd'].map((memberVnfd
) => {
693 memberVnfd
['name'] && delete memberVnfd
['name'];
696 nsdPayload
['ns-placement-groups'] && delete nsdPayload
['ns-placement-groups'];
697 nsdPayload
['vnf-placement-groups'] && delete nsdPayload
['vnf-placement-groups'];
698 nsdPayload
.vld
= this.state
.vld
;
699 nsdPayload
.vld
&& nsdPayload
.vld
.map(function(v
){
703 nsdPayload
['input-parameter-xpath'] && nsdPayload
['input-parameter-xpath'].map((x
) => delete x
.value
);
709 "description": "a description for " + guuid
,
710 "admin-status": launch
? "ENABLED" : "DISABLED",
714 if(!this.state
.selectedResourceOrchestrator
) {
715 Alt
.actions
.global
.showNotification
.defer("No Resource Orchestrator selected");
718 if (this.state
.selectedResourceOrchestrator
.name
!= "rift") {
719 payload
["resource-orchestrator"] = this.state
.selectedResourceOrchestrator
.name
;
722 if(!this.state
.dataCenterID
) {
723 Alt
.actions
.global
.showNotification
.defer("No Data Center selected");
726 payload
["datacenter"] = this.state
.dataCenterID
;
728 //Clean Input Parameters
729 if (this.state
.hasConfigureNSD
) {
730 let ips
= _cloneDeep(this.state
['input-parameters']);
732 let ipsToSend
= ips
.filter(function(ip
) {
733 if (ip
.value
&& ip
.value
!= "") {
736 delete ip
['default-value'];
742 if (ipsToSend
.length
> 0) {
743 payload
['input-parameter'] = ipsToSend
;
746 //Clean VNF Input Parameters
747 if (this.state
.hasConfigureVNFD
) {
748 let vnf
= _cloneDeep(this.state
['vnf-input-parameter']);
749 vnf
= vnf
.filter(function(v
){
751 v
['input-parameter'] = v
['input-parameter'].filter(
753 if(i
.value
&& i
.value
!= "") {
755 delete i
['default-value'];
760 if (v
['input-parameter'].length
) {
765 if (vnf
.length
> 0) {
766 payload
['vnf-input-parameter'] = vnf
;
769 let VnfDataCenters
= this.state
.vnfDataCenters
;
770 if (Object
.keys(VnfDataCenters
).length
) {
771 payload
['vnf-datacenter-map'] = Object
.keys(VnfDataCenters
).map(function(k
) {
773 'member-vnf-index-ref' : k
,
774 datacenter
: VnfDataCenters
[k
].datacenter
778 // These placement groups need to be refactored. Too much boilerplate.
779 if (this.state
.displayPlacementGroups
) {
780 nsPg
= this.state
['ns-placement-groups'];
781 vnfPg
= this.state
['vnf-placement-groups'];
782 if(nsPg
&& (nsPg
.length
> 0)) {
783 payload
['nsd-placement-group-maps'] = nsPg
.map(function(n
, i
) {
784 if(n
['availability-zone'] || n
['server-group'] || (n
['host-aggregate'].length
> 0)) {
786 'cloud-type': self
.state
.dataCenterType
788 if(n
['host-aggregate'].length
> 0) {
789 obj
['host-aggregate'] = n
['host-aggregate'].map(function(h
, j
) {
791 'metadata-key': h
.key
,
792 'metadata-value': h
.value
796 if(n
['availability-zone'] && (n
['availability-zone'] != '')) {
797 obj
['availability-zone'] = {name
: n
['availability-zone']};
799 if(n
['server-group'] && (n
['server-group'] != '')) {
800 obj
['server-group'] = {name
: n
['server-group']};
802 obj
['placement-group-ref'] = n
.name
;
805 }).filter(function(o
){
813 if(vnfPg
&& (vnfPg
.length
> 0)) {
814 let vnfDataCenterDictionary
= {};
815 payload
['vnf-datacenter-map'] && payload
['vnf-datacenter-map'].map(function(d
) {
816 vnfDataCenterDictionary
[d
['member-vnf-index-ref']] = d
.datacenter
818 payload
['vnfd-placement-group-maps'] = vnfPg
.map(function(n
, i
) {
819 if(n
['availability-zone'] || n
['server-group'] || (n
['host-aggregate'].length
> 0)) {
820 let DC
= vnfDataCenterDictionary
[n
['member-vnf-index']];
822 'cloud-type': DC
? _find(self
.state
.selectedResourceOrchestrator
.datacenters
.datacenters
, {name
: DC
})['datacenter-type'] : self
.state
.dataCenterType
824 if(n
['host-aggregate'].length
> 0) {
825 obj
['host-aggregate'] = n
['host-aggregate'].map(function(h
, j
) {
827 'metadata-key': h
.key
,
828 'metadata-value': h
.value
832 if(n
['server-group'] && (n
['server-group'] != '')) {
833 obj
['server-group'] = {name
: n
['server-group']};
835 if(n
['availability-zone'] && (n
['availability-zone'] != '')) {
836 obj
['availability-zone'] = {name
: n
['availability-zone']};
838 obj
['placement-group-ref'] = n
.name
;
839 obj
['vnfd-id-ref'] = n
['vnfd-id-ref'];
842 }).filter(function(o
){
853 payload
['ssh-authorized-key'] = this.state
.sshKeysRef
.map(function(k
) {
854 return {'key-pair-ref': JSON
.parse(k
).name
};
857 payload
['user'] = addKeyPairRefToUsers(this.state
.usersList
);
866 function addKeyPairRefToUsers(list
) {
867 return list
.map(function(u
) {
870 'user-info': u
['user-info'],
871 'ssh-authorized-key': u
['ssh-authorized-key'].map(function(k
) {
880 function getMockSLA(id
) {
881 console
.log('Getting mock SLA Data for id: ' + id
);
883 sla_parameters
: slaData
887 function getMockData() {
888 console
.log('Getting mock Descriptor Data');
895 export default LaunchNetworkServiceStore
;