Instantiate placement groups input fix
[osm/UI.git] / skyquake / plugins / launchpad / src / instantiate / instantiateInputParams.jsx
1
2 /*
3  *
4  *   Copyright 2016 RIFT.IO Inc
5  *
6  *   Licensed under the Apache License, Version 2.0 (the "License");
7  *   you may not use this file except in compliance with the License.
8  *   You may obtain a copy of the License at
9  *
10  *       http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *   Unless required by applicable law or agreed to in writing, software
13  *   distributed under the License is distributed on an "AS IS" BASIS,
14  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *   See the License for the specific language governing permissions and
16  *   limitations under the License.
17  *
18  */
19 import React, {Component} from 'react';
20 import ReactDOM from 'react-dom';
21 import SelectOption from 'widgets/form_controls/selectOption.jsx';
22 import imgAdd from '../../node_modules/open-iconic/svg/plus.svg'
23 import imgRemove from '../../node_modules/open-iconic/svg/trash.svg'
24 import TextInput from 'widgets/form_controls/textInput.jsx';
25 import './instantiateInputParams.scss';
26
27 export default class InstantiateInputParams extends Component {
28   constructor(props) {
29     super(props);
30   }
31   nsConfigHTML = (props) => {
32     return (
33       <div className="configure-nsd_section">
34         <div className="inputControls">
35             <TextInput label="Instance Name" type="text" pattern="^[a-zA-Z0-9_]*$" style={{textAlign:'left'}} onChange={props.updateName} value={props.name}/>
36           {
37             !isOpenMano(props.ro) ?
38               (
39                 <label>Select VIM Account
40                   <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} onChange={props.nsFn.updateSelectedCloudAccount} />
41                 </label>
42               )
43             : null
44           }
45           {
46             isOpenMano(props.ro) ?
47               dataCentersHTML(props.dataCenters[props.ro.name],
48                               props.nsFn.updateSelectedDataCenter)
49               : null
50           }
51         </div>
52       </div>
53     )
54   }
55   vnfCloudAccountsHTML = (props) => {
56     let nsd = props.nsd;
57     let dataCenters = props.dataCenters;
58     return (
59       <div className="configure-nsd_section">
60         <h3 className="launchpadCard_title">NS/VNF ACCOUNT PLACEMENTS</h3>
61         {
62
63             //selectedNSDid
64               nsd['constituent-vnfd'] && nsd['constituent-vnfd'].map(function(v, i) {
65                 let defaultValue = false;
66                 if(props.vnfdCloudAccounts && props.vnfdCloudAccounts.hasOwnProperty(v['member-vnf-index'])) {
67                   defaultValue = props.vnfdCloudAccounts[v['member-vnf-index']]
68                 }
69                 return (
70                     <div className="inputControls" key={i}>
71                     <h4 className="inputControls-title">VNFD: {v.name}</h4>
72                   {
73                     !isOpenMano(props.ro) ?
74                       (
75                         <label>Select VIM Account
76                           <SelectOption options={constructCloudAccountOptions(props.cloudAccounts)} initial={true} onChange={props.vnfFn.updateSelectedCloudAccount.bind(null, v['member-vnf-index'])} defaultValue={defaultValue} />
77                         </label>
78                       )
79                     : null
80                   }
81                       {
82                         isOpenMano(props.ro) ?
83                           dataCentersHTML(
84                                           props.dataCenters[props.ro.name],
85                                           props.vnfFn.updateSelectedDataCenter.bind(null, v['member-vnf-index']), true)
86                           : null
87                       }
88                       {
89                         (props.configAgentAccounts && props.configAgentAccounts.length > 0) ?
90                         <label>Select Config Agent Account
91                           <SelectOption options={props.configAgentAccounts && props.configAgentAccounts.map(function(c) {
92                             return {
93                               label: c.name,
94                               value: c.name
95                             }
96                           })} initial={true} onChange={props.vnfFn.updateSelectedConfigAgent(v['member-vnf-index'])} defaultValue={false} />
97                         </label> : null
98                       }
99                     </div>
100                 )
101               })
102         }
103       </div>
104     )
105   }
106   inputParametersHTML = (props) => {
107     let inputParameters = props.inputParameters;
108     const handleChange = (i, event) => props.updateInputParam(i, event.target.value);
109     return inputParameters && inputParameters.map(function(input, i) {
110         return (
111                 <div className="configure-nsd_section" key={i}>
112                   <h3 className="launchpadCard_title">Input Parameters</h3>
113                   <div className="inputControls">
114                       <TextInput label={ input.label || input.xpath } type="text" onChange={handleChange.bind(this, i)} />
115                   </div>
116                 </div>
117         )
118       })
119   }
120   nsPlacementGroupsHTML = (props) => {
121     let nsPlacementGroups = props.nsPlacementGroups;
122     let displayPlacementGroups = props.displayPlacementGroups;
123     if (nsPlacementGroups && nsPlacementGroups.length > 0 && displayPlacementGroups) {
124       return (
125         <div className="configure-nsd_section">
126           <h3 className="launchpadCard_title">NS Placement Groups</h3>
127             {
128               nsPlacementGroups.map(function(input, i) {
129                 return (
130                   <div  key={i} className="configure-nsd_section-info">
131                     <div className="placementGroup_description">
132                       <div className="placementGroup_description-name">
133                         <strong>{input.name}</strong> contains: {
134                           input['member-vnfd'].map((m,i) => {
135                             let s = m.name;
136                             if(i>0) {
137                               s = ', ' + m.name
138                             };
139                             return s;
140                           })
141                         }
142                       </div>
143                       <div><em>{input.requirement}</em></div>
144                       <div><strong>Strategy:</strong> {input.strategy}</div>
145                     </div>
146                     <label>
147                       <span> Availability Zone <span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span> </span>
148                       <div  style={{display:'none'}}>
149                       <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, 'availability-zone')} />
150                       <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
151                       </div>
152                     </label>
153                     <label>
154                       <span> Affinity/Anti-affinity Server Group<span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
155                       <div style={{display:'none'}}>
156                         <TextInput type="text" onChange={props.nsFn.placementGroupUpdate.bind(self, i, 'server-group')} />
157                         <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
158                       </div>
159                     </label>
160                     <div className="host-aggregate">
161                       <label>
162                         <span> Host Aggregates <span onClick={props.nsFn.addHostAggregate.bind(self, i)} className="addInput"  ><img src={imgAdd} />Add</span></span>
163                       {
164                         input['host-aggregate'].length > 0 ?
165                           input['host-aggregate'].map((h,j) => {
166                             let key = h.key || '';
167                             let value = h.value || '';
168                             return (
169
170                                   <div className="input_group" key={j}>
171                                     <TextInput type="text" onChange={props.nsFn.hostAggregateUpdate.bind(self, i, j, 'key')} placeholder="KEY" value={key} />
172                                     <TextInput type="text" onChange={props.nsFn.hostAggregateUpdate.bind(self, i, j, 'value')} placeholder="VALUE"  value={value} />
173                                     <span onClick={props.nsFn.removeHostAggregate.bind(self, i, j)} className="removeInput"><img src={imgRemove} />Remove</span>
174                                   </div>
175                             )
176                           }) : ''
177                       }
178                       </label>
179                     </div>
180                     </div>
181                 );
182               })
183             }
184        </div>
185      );
186     }
187   }
188   vnfPlacementGroupsHTML = (props) => {
189     let vnfPlacementGroups = props.vnfPlacementGroups;
190     let displayPlacementGroups = props.displayPlacementGroups;
191     if (vnfPlacementGroups && vnfPlacementGroups.length > 0 && displayPlacementGroups) {
192       return vnfPlacementGroups.map(function(input, i) {
193             return (
194               <div className="configure-nsd_section" key={i}>
195                 <h3 className="launchpadCard_title">{input['vnf-name']} VNF Placement Group</h3>
196                   <div className="configure-nsd_section-info">
197                     <div className="placementGroup_description">
198                       <div className="placementGroup_description-name">
199                         <strong>{input.name}</strong> contains: {
200                           input['member-vdus'].map((m,i) => {
201                             let s = m['member-vdu-ref'];
202                             if(i>0) {
203                               s = ', ' + m['member-vdu-ref']
204                             };
205                             return s;
206                           })
207                         }
208                       </div>
209                       <div><em>{input.requirement}</em></div>
210                       <div><strong>Strategy</strong>: {input.strategy}</div>
211                     </div>
212                     <label>
213                       <span> Availability Zone <span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
214                       <div  style={{display:'none'}}>
215                         <TextInput type="text" onChange={props.vnfFn.placementGroupUpdate.bind(self, i, 'availability-zone')} />
216                            <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
217                       </div>
218                     </label>
219                     <label>
220                       <span> Affinity/Anti-affinity Server Group<span onClick={showInput} className="addInput"><img src={imgAdd} />Add</span></span>
221                       <div  style={{display:'none'}}>
222                         <TextInput type="text" onChange={props.vnfFn.placementGroupUpdate.bind(self, i, 'server-group')} />
223                          <span onClick={hideInput} className="removeInput"><img src={imgRemove} />Remove</span>
224                       </div>
225                     </label>
226                     <div className="host-aggregate">
227                     <label>
228                       <span> Host Aggregates <span onClick={props.vnfFn.addHostAggregate.bind(self, i)} className="addInput"><img src={imgAdd} />Add</span></span>
229                       {
230                         input['host-aggregate'].length > 0 ?
231                           input['host-aggregate'].map((h,j) => {
232                             let key = h.key || '';
233                             let value = h.value || '';
234                             return (
235
236                                   <div className="input_group" key={j}>
237                                     <TextInput type="text" onChange={props.vnfFn.hostAggregateUpdate.bind(self, i, j, 'key')} placeholder="KEY" value={key} />
238                                     <TextInput type="text" onChange={props.vnfFn.hostAggregateUpdate.bind(self, i, j, 'value')} placeholder="VALUE"  value={value} />
239                                     <span onClick={props.vnfFn.removeHostAggregate.bind(self, i, j)} className="removeInput"><img src={imgRemove} />Remove</span>
240                                   </div>
241
242                             )
243                           }) : ''
244                       }
245                       </label>
246                     </div>
247                     </div>
248                 </div>
249             );
250           });
251     }
252   }
253   vldsHTML = (props) => {
254     let self = this;
255     let ipProfileList = props.ipProfileList;
256     let vlds = props.vlds;
257     return vlds && (
258       <div className="configure-nsd_section">
259         <h3 className="launchpadCard_title">VLDs</h3>
260             {vlds && vlds.map(function(v, i) {
261                   let currentType = v.type;
262                   let isVIM = (currentType == 'vim-network-name');
263                   let isUnknown = (currentType == 'none') || ((currentType != 'vim-network-name') && (currentType != 'ip-profile-ref'));
264                   return (
265                     <div key={self.props.nsd.id + '-' + i} className="inputControls">
266                         <h4 className="inputControls-title">VLD: {v['short-name'] ? v['short-name'] : v['name']}</h4>
267                         <label><span>Specify VLD Parameters</span></label>
268                         <div  className="inputControls-radioGroup">
269                           <label className="inputControls-radio" style={{display: ipProfileList ? 'flex' : 'none'}}>
270                             <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={!isVIM && !isUnknown} value='ip-profile-ref' />
271                             IP Profile
272                           </label>
273                           <label className="inputControls-radio">
274                             <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isVIM && !isUnknown} value='vim-network-name' />
275                             VIM Network Name
276                           </label>
277                           <label className="inputControls-radio">
278                             <input type="radio" name={'vld-' + i } onChange={self.props.vldFn.updateType(i)} checked={isUnknown} value='none' />
279                             None
280                           </label>
281                         </div>
282                           {
283                             isUnknown ? null : isVIM ?
284                             <TextInput label="Network Name" onChange={self.props.vldFn.updateValue(i, currentType)} value={v[currentType]} /> :
285                             <div>
286                               <SelectOption
287                               label="IP PROFILE NAME"
288                                 options={ipProfileList && ipProfileList.map(function(ip) {
289                                   return {
290                                     label: ip.name,
291                                     value: ip.name
292                                   }
293                                 })}
294                                 initial={
295                                   v['ip-profile-ref'] ? false : true
296                                 }
297                                 defaultValue={v['ip-profile-ref']}
298                                 onChange={self.props.vldFn.updateValue(i, currentType)}>
299                               </SelectOption>
300
301                             </div>
302                           }
303                     </div>
304                   )
305                 })}
306       </div>
307     );
308   }
309   ipProfilesHTML = (props) => {
310     let vldHasIPprofile = false;
311     props.vlds && props.vlds.map(function(v){
312       if(v.type == 'ip-profile-ref') {
313         vldHasIPprofile = true;
314       }
315     })
316     let ipProfileList = props.ipProfileList;
317     return ipProfileList && vldHasIPprofile &&
318       (
319       <div className="configure-nsd_section">
320         <h3 className="launchpadCard_title">IP Profiles</h3>
321         {
322           //IP Config
323           ipProfileList && ipProfileList.map(function(ip, j) {
324             let ipl = ip['ip-profile-params'];
325               return (
326                 <div className="inputControls" key={j}>
327                   <div className="inputControls-title" >
328                     {ip.name}
329                   </div>
330                   <div  className="inputControls-radioGroup">
331                     <label className="inputControls-radio">
332                       <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'ipv4'} value='ipv4' />
333                       ipv4
334                     </label>
335                     <label className="inputControls-radio">
336                       <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'ipv6'} value='ipv6' />
337                       ipv6
338                     </label>
339                     <label className="inputControls-radio">
340                       <input type="radio" name={'ip-profile-' + j } onChange={props.ipProfileFn.updateVersion(j)} checked={ipl['ip-version'] == 'unknown'} value='unknown' />
341                       unknown
342                     </label>
343                   </div>
344                   <TextInput
345                     label="subnet address"
346                     onChange={props.ipProfileFn.updateProfile(j, 'subnet-address')}
347                     value={ipl['subnet-address']}
348                     />
349                   <TextInput
350                     label="gateway address"
351                     onChange={props.ipProfileFn.updateProfile(j, 'gateway-address')}
352                     value={ipl['gateway-address']}
353                     />
354                   <TextInput
355                     label="security group"
356                     onChange={props.ipProfileFn.updateProfile(j, 'security-group')}
357                     value={ipl['security-group']}
358                     />
359                   <TextInput
360                     label="subnet prefix pool"
361                     onChange={props.ipProfileFn.updateProfile(j, 'subnet-prefix-pool')}
362                     value={ipl['subnet-prefix-pool']}
363                     />
364                     <label>
365                       <div style={{display:'flex'}}>
366                         DNS SERVERS <span onClick={props.dnsFn.addDNS(j)} className="addInput"><img src={imgAdd} />Add</span>
367                       </div>
368                       {
369                         ipl['dns-server'] && ipl['dns-server'].map(function(dns, k) {
370                           return (
371                             <div key={k} style={{display:'flex'}}>
372                               <TextInput
373                                   onChange={props.dnsFn.updateDNS(j,k)}
374                                   value={ipl['dns-server'][k].address}
375                                   />
376                               <span onClick={props.dnsFn.removeDNS(j,k)} className="removeInput">
377                                 <img src={imgRemove} />Remove</span>
378                             </div>
379                           )
380                         })
381                       }
382                     </label>
383                   <div  className="inputControls-radioGroup">
384                     <label className="inputControls-radio">
385                     DHCP ENABLED
386                       <input type="radio"
387                         name={'ip-profile-dhcp' + j }
388                         onChange={props.ipProfileFn.updateDHCP(j, 'enabled')}
389                         checked={ipl.hasOwnProperty('dhcp-params') && ipl['dhcp-params'].enabled}
390                         value={true} />
391                       YES
392                     </label>
393                     <label className="inputControls-radio">
394                       <input type="radio"
395                         name={'ip-profile-dhcp' + j }
396                         onChange={props.ipProfileFn.updateDHCP(j, 'enabled')}
397                         checked={!ipl.hasOwnProperty('dhcp-params') || !ipl['dhcp-params'].enabled}
398                         value={false} />
399                       NO
400                     </label>
401                   </div>
402                   {
403                     (ipl['dhcp-params'] && ipl['dhcp-params'].enabled) ? dhcpHTML(props, ipl, j) : null
404                   }
405                 </div>
406               )
407           })
408         }
409         </div>);
410     function dhcpHTML(props, ipl, j){
411       return (<div>
412                   <TextInput
413                     label="DHCP Start Address"
414                     onChange={props.ipProfileFn.updateDHCP(j, 'start-address')}
415                     value={ipl['dhcp-params'] && ipl['dhcp-params']['start-address']}
416                     />
417                   <TextInput
418                     label="DHCP Count"
419                     onChange={props.ipProfileFn.updateDHCP(j, 'count')}
420                     value={ipl['dhcp-params'] && ipl['dhcp-params']['count']}
421                     />
422                 </div>
423                 );
424     }
425   }
426   sshKeysHTML = (props) => {
427     let sshKeysList = props.sshKeysList;
428     let sshKeysRef = props.sshKeysRef;
429     if(sshKeysList && sshKeysList.length > 0) {
430       return (
431         <div className="configure-nsd_section">
432           <h3 className="launchpadCard_title">SSH Authorized Keys</h3>
433
434             {
435               sshKeysRef.map(function(ref, i) {
436                 let keyref = JSON.stringify(ref)
437                 return (
438                   <div key={keyref.name + '-' + i} className="inputControls inputControls-sshkeys">
439                     <label>
440                       <div>
441                       <SelectOption
442                         label="Key Pair"
443                         options={sshKeysList && sshKeysList.map(function(k) {
444                           return {
445                             label: k.name,
446                             value: k
447                           }
448                         })}
449                         ref="keyPairSelection"
450                         initial={false}
451                         defaultValue={keyref.name || sshKeysList[0].name}
452                         onChange={props.sshFn.updateKeyRef(i)}>
453                       </SelectOption>
454                       </div>
455                     </label>
456                     <label>
457                       <span onClick={props.sshFn.updateKeyRef(i, true)} className="removeInput">
458                         <img src={imgRemove} />
459                         Remove
460                       </span>
461                     </label>
462                   </div>
463                 )
464               })
465             }
466             <div className="inputControls inputControls-sshkeys ">
467               <label style={{display: 'flex', 'flexDirection': 'row'}}>
468               SSH KEY PAIR
469                 <span onClick={props.sshFn.updateKeyRef().bind(null, {target:{value: JSON.stringify(sshKeysList[0])}})} className="addInput">
470                   <img src={imgAdd} />
471                   ADD
472                 </span>
473               </label>
474             </div>
475         </div>
476       );
477     }
478   }
479   usersHTML = (props) => {
480     let usersFn = props.usersFn;
481     let sshKeysList = props.sshKeysList;
482     let usersList = props.usersList && props.usersList.map(function(u, i) {
483       let sshKeysRef = u['ssh-authorized-key'];
484       return (
485         <div className="input_group input_group-users" key={i}>
486           <div className="inputControls">
487           <div style={{fontWeight: 'bold', display: 'flex'}}>USER <span onClick={usersFn.remove(i)} className="removeInput"><img src={imgRemove} />Remove</span></div>
488             <TextInput onChange={usersFn.update(i, 'name')} label="USERNAME" value={i.name} />
489             <TextInput onChange={usersFn.update(i, 'user-info')} label="REAL NAME" value={i.gecos} />
490             {
491               sshKeysRef.map(function(ref, j) {
492                 let keyref = JSON.stringify(ref)
493                 return (
494                   <div key={keyref.name + '-' + i + '-' + j} className="inputControls inputControls-sshkeys">
495                     <label>
496                       <div>
497                       <SelectOption
498                         label="Key Pair"
499                         options={sshKeysList && sshKeysList.map(function(k) {
500                           return {
501                             label: k.name,
502                             value: k
503                           }
504                         })}
505                         ref="keyPairSelection"
506                         initial={false}
507                         defaultValue={ref}
508                         onChange={usersFn.updateSSHkeyRef(i, j)}>
509                       </SelectOption>
510                       </div>
511                     </label>
512                     {
513                       sshKeysRef.length > 0 ?
514                         <label>
515                           <span onClick={usersFn.updateSSHkeyRef(i, j, true)} className="removeInput">
516                             <img src={imgRemove} />
517                             Remove
518                           </span>
519                         </label>
520                       : null
521                     }
522
523                   </div>
524                 )
525               })
526             }
527               <div className="inputControls inputControls-sshkeys ">
528                 <label style={{display: 'flex', 'flexDirection': 'row', 'alignItems': 'center'}}>
529                 SSH KEY PAIR
530                   <span onClick={usersFn.updateSSHkeyRef(i).bind(null, {target:{value: JSON.stringify(sshKeysList[0])}})} className="addInput">
531                     <img src={imgAdd} />
532                     ADD
533                   </span>
534                 </label>
535               </div>
536           </div>
537         </div>
538       )
539     });
540     return (
541       <div className="configure-nsd_section">
542         <h3 className="launchpadCard_title">USERS</h3>
543         {usersList}
544         <div className="inputControls inputControls-sshkeys inputControls-addUser ">
545             <span onClick={usersFn.add(sshKeysList)} className="addInput">
546               <img src={imgAdd} />
547               ADD USER
548             </span>
549         </div>
550       </div>
551     )
552   }
553
554   render() {
555     const props = this.props;
556     let html;
557     let self = this;
558
559     html = (
560         <div className="instantiateInputParams">
561           {
562             //NS NAMEA AND CLOUD
563             this.nsConfigHTML(props)
564           }
565           {
566             //VNF VIM ACCOUNTS
567             this.vnfCloudAccountsHTML(props)
568           }
569           {
570             //INPUT PARAMETERS
571             this.inputParametersHTML(props)
572           }
573           {
574             //NS PLACEMENTGROUPS
575             this.nsPlacementGroupsHTML(props)
576           }
577           {
578             //VNF PLACEMENTGROUPS
579             this.vnfPlacementGroupsHTML(props)
580           }
581           {
582             //VLD CONFIGURATION
583             this.vldsHTML(props)
584           }
585           {
586             //IP PROFILE CONFIGURATION
587             this.ipProfilesHTML(props)
588           }
589           {
590             //SSH KEY ASSIGNMENTS
591             this.sshKeysHTML(props)
592           }
593           {
594             //USER MANAGEMENT
595             this.usersHTML(props)
596           }
597         </div>
598     )
599     return html;
600   }
601 }
602 function showInput(e){
603   let target = e.target;
604   if(target.parentElement.classList.contains("addInput")) {
605     target = target.parentElement;
606   }
607   target.style.display = 'none';
608   target.parentElement.nextElementSibling.style.display = 'flex';
609   // e.target.parentElement.nextElementSibling.children[1].style.display = 'initial';
610 }
611 function hideInput(e){
612   let target = e.target;
613   if(target.parentElement.classList.contains("removeInput")) {
614     target = target.parentElement;
615   }
616   target.parentElement.style.display = 'none';
617   target.parentElement.previousElementSibling.children[1].style.display = 'inline';
618   target.previousSibling.value = '';
619 }
620 function addDNS(){}
621 function removeDNS(){}
622 function constructCloudAccountOptions(cloudAccounts){
623   let CloudAccountOptions = cloudAccounts && cloudAccounts.map(function(ca, index) {
624     return {
625       label: ca.name,
626       value: ca
627     }
628   });
629   return CloudAccountOptions;
630 }
631 function dataCentersHTML(dataCenters, onChange, initial) {
632   //Build DataCenter options
633   //Relook at this, why is it an object?
634   let DataCenterOptions = [];
635   DataCenterOptions = dataCenters && dataCenters.map(function(dc, index) {
636     return {
637       label: dc.name,
638       value: dc.uuid
639     }
640   });
641   if (dataCenters && dataCenters.length > 0) {
642     return (
643       <label>Select Data Center
644         <SelectOption initial={!!initial} options={DataCenterOptions} onChange={onChange} />
645       </label>
646     )
647   }
648 }
649 function isOpenMano(account) {
650   if (account) {
651     let a = account;
652     if (a.constructor.name == 'String') {
653       a = JSON.parse(a);
654     }
655     return a['account-type'] == 'openmano';
656   } else {
657     return false;
658   }
659 }
660 function updateNewSshKeyRefSelection(e) {
661   this.setState({
662     newRefSelection: e.target.value
663   })
664 }
665 function resetRef() {
666     this.setState({
667     newRefSelection: null
668   })
669 }
670 InstantiateInputParams.defaultProps = {
671   data: [],
672   sshKeysList: [],
673   sshKeysRef: [],
674   users: {}
675 }