Guest User

Untitled

a guest
Sep 2nd, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 35.99 KB | None | 0 0
  1. diff --git a/package.json b/package.json
  2. index 1b0329e..35e4d63 100644
  3. --- a/package.json
  4. +++ b/package.json
  5. @@ -74,7 +74,7 @@
  6. "lint:fix": "yarn lint:js --fix && yarn lint:styles --fix",
  7. "lint:js": "eslint --max-warnings 0 src storybook",
  8. "lint:styles": "yarn stylelint",
  9. - "prettier": "prettier --write src/**/*.js'"
  10. + "prettier": "prettier --write 'src/**/*.js'"
  11. },
  12. "jest": {
  13. "collectCoverageFrom": [
  14. diff --git a/src/components/buttons/ButtonWithIcon.js b/src/components/buttons/ButtonWithIcon.js
  15. index d8ce461..63d4603 100644
  16. --- a/src/components/buttons/ButtonWithIcon.js
  17. +++ b/src/components/buttons/ButtonWithIcon.js
  18. @@ -2,15 +2,15 @@ import React from 'react';
  19. import { Button, Icon, Col } from 'patternfly-react';
  20. import './ButtonWithIcon.css';
  21.  
  22. -export const ButtonWithIcon = (props) => {
  23. +export const ButtonWithIcon = props => {
  24. return (
  25. <Button onClick={props.onClick} bsClass="btn btn-link btn-with-icon">
  26. <Col md={12}>
  27. - <Icon type={props.iconType} name={props.icon} className="fa-5x"/>
  28. + <Icon type={props.iconType} name={props.icon} className="fa-5x" />
  29. </Col>
  30. <Col md={12} className="label-column">
  31. <span className="lead">{props.label}</span>
  32. </Col>
  33. </Button>
  34. );
  35. -}
  36. +};
  37. diff --git a/src/components/forms/FormFactory.js b/src/components/forms/FormFactory.js
  38. index bc6d2e6..58e86ca 100644
  39. --- a/src/components/forms/FormFactory.js
  40. +++ b/src/components/forms/FormFactory.js
  41. @@ -1,20 +1,20 @@
  42. import React from 'react';
  43. import {
  44. - FormControl,
  45. - FormGroup,
  46. - Col,
  47. - ControlLabel,
  48. - HelpBlock,
  49. - ButtonGroup,
  50. - DropdownButton,
  51. - MenuItem,
  52. - Checkbox,
  53. - Form
  54. - } from 'patternfly-react';
  55. - import { get, has } from 'lodash';
  56. - import './FormFactory.css';
  57. + FormControl,
  58. + FormGroup,
  59. + Col,
  60. + ControlLabel,
  61. + HelpBlock,
  62. + ButtonGroup,
  63. + DropdownButton,
  64. + MenuItem,
  65. + Checkbox,
  66. + Form
  67. +} from 'patternfly-react';
  68. +import { get, has } from 'lodash';
  69. +import './FormFactory.css';
  70.  
  71. -export const FormFactory = (props) => {
  72. +export const FormFactory = props => {
  73. const formGroups = Object.keys(props.fields)
  74. .filter(key => !(props.fields[key].isVisible && props.fields[key].isVisible(props.fieldsValues) === false))
  75. .map(key => {
  76. @@ -22,51 +22,73 @@ export const FormFactory = (props) => {
  77. const validMsg = get(props.fieldsValues[key], 'validMsg', null);
  78. switch (props.fields[key].type) {
  79. case 'textarea':
  80. - child = <FormControl
  81. - componentClass="textarea"
  82. - value={get(props.fieldsValues[key], 'value', '')}
  83. - onChange={event => props.onFormChange(event.target.value, key)}
  84. - />;
  85. + child = (
  86. + <FormControl
  87. + componentClass="textarea"
  88. + value={get(props.fieldsValues[key], 'value', '')}
  89. + onChange={event => props.onFormChange(event.target.value, key)}
  90. + />
  91. + );
  92. break;
  93. case 'dropdown':
  94. - child = <ButtonGroup justified>
  95. - <DropdownButton
  96. - id={`dropdown-${key}`}
  97. - bsStyle="default"
  98. - className="form-dropdown"
  99. - title={has(props.fieldsValues[key], 'value') ? props.fieldsValues[key].value : props.fields[key].default}
  100. - onSelect={value => props.onFormChange(value, key)}>
  101. - {props.fields[key].values.map(value => <MenuItem key={value.id ? value.id : value.name} eventKey={value.id ? value.id : value.name}>{value.name}</MenuItem>)}
  102. - </DropdownButton>
  103. - </ButtonGroup>;
  104. + child = (
  105. + <ButtonGroup justified>
  106. + <DropdownButton
  107. + id={`dropdown-${key}`}
  108. + bsStyle="default"
  109. + className="form-dropdown"
  110. + title={
  111. + has(props.fieldsValues[key], 'value') ? props.fieldsValues[key].value : props.fields[key].default
  112. + }
  113. + onSelect={value => props.onFormChange(value, key)}
  114. + >
  115. + {props.fields[key].values.map(value => (
  116. + <MenuItem key={value.id ? value.id : value.name} eventKey={value.id ? value.id : value.name}>
  117. + {value.name}
  118. + </MenuItem>
  119. + ))}
  120. + </DropdownButton>
  121. + </ButtonGroup>
  122. + );
  123. break;
  124. case 'checkbox':
  125. - child = <Checkbox
  126. - checked={get(props.fieldsValues[key], 'value', false)}
  127. - onChange={event => props.onFormChange(event.target.checked, key)}
  128. - >
  129. - {props.fields[key].title}
  130. - </Checkbox>;
  131. + child = (
  132. + <Checkbox
  133. + checked={get(props.fieldsValues[key], 'value', false)}
  134. + onChange={event => props.onFormChange(event.target.checked, key)}
  135. + >
  136. + {props.fields[key].title}
  137. + </Checkbox>
  138. + );
  139. break;
  140. default:
  141. - child = <FormControl
  142. - type="text"
  143. - value={get(props.fieldsValues[key], 'value', '')}
  144. - onChange={event => props.onFormChange(event.target.value, key)}
  145. - />;
  146. + child = (
  147. + <FormControl
  148. + type="text"
  149. + value={get(props.fieldsValues[key], 'value', '')}
  150. + onChange={event => props.onFormChange(event.target.value, key)}
  151. + />
  152. + );
  153. }
  154. return (
  155. - <FormGroup key={key} validationState={validMsg ? 'error' : null} className={props.fields[key].noBottom ? 'form-group-no-bottom' : undefined}>
  156. - <Col sm={3} className="text-right">
  157. - {props.fields[key].type === 'checkbox' ? null:
  158. - <ControlLabel className={props.fields[key].required ? 'required-pf': null}>{props.fields[key].title}</ControlLabel>}
  159. - </Col>
  160. - <Col sm={5}>
  161. - {child}
  162. - <HelpBlock>{validMsg ? validMsg: null}</HelpBlock>
  163. - </Col>
  164. - </FormGroup>);
  165. + <FormGroup
  166. + key={key}
  167. + validationState={validMsg ? 'error' : null}
  168. + className={props.fields[key].noBottom ? 'form-group-no-bottom' : undefined}
  169. + >
  170. + <Col sm={3} className="text-right">
  171. + {props.fields[key].type === 'checkbox' ? null : (
  172. + <ControlLabel className={props.fields[key].required ? 'required-pf' : null}>
  173. + {props.fields[key].title}
  174. + </ControlLabel>
  175. + )}
  176. + </Col>
  177. + <Col sm={5}>
  178. + {child}
  179. + <HelpBlock>{validMsg ? validMsg : null}</HelpBlock>
  180. + </Col>
  181. + </FormGroup>
  182. + );
  183. });
  184. - return <Form horizontal>{formGroups}</Form>;
  185. -
  186. -}
  187. + return <Form horizontal>{formGroups}</Form>;
  188. +};
  189. diff --git a/src/components/wizards/create-vm/CreateVmWizard.js b/src/components/wizards/create-vm/CreateVmWizard.js
  190. index f7a524d..85fbac2 100644
  191. --- a/src/components/wizards/create-vm/CreateVmWizard.js
  192. +++ b/src/components/wizards/create-vm/CreateVmWizard.js
  193. @@ -1,207 +1,217 @@
  194. import React from 'react';
  195. import { Wizard } from 'patternfly-react';
  196. -import { get } from 'lodash';
  197. +import { get } from 'lodash';
  198. import { createVM } from '../../../k8s/request';
  199. import { FormFactory } from '../../forms/FormFactory';
  200.  
  201. export class CreateVmWizard extends React.Component {
  202. + state = {
  203. + activeStepIndex: 0,
  204. + basicVmSettings: {},
  205. + wizardValid: false
  206. + };
  207.  
  208. - state = {
  209. - activeStepIndex: 0,
  210. - basicVmSettings: {},
  211. - wizardValid: false
  212. + onFormChange = (newValue, target) => {
  213. + let validMsg = null;
  214. + if (this.basicFormFields[target].required && newValue.trim().length === 0) {
  215. + validMsg = `${this.basicFormFields[target].title} is required`;
  216. }
  217. -
  218. - onFormChange = (newValue, target) => {
  219. - let validMsg = null;
  220. - if (this.basicFormFields[target].required && newValue.trim().length === 0){
  221. - validMsg = `${this.basicFormFields[target].title} is required`;
  222. + const basicVmSettings = {
  223. + ...this.state.basicVmSettings,
  224. + [target]: {
  225. + value: newValue,
  226. + validMsg
  227. }
  228. - const basicVmSettings = {
  229. - ...this.state.basicVmSettings,
  230. - [target]: {
  231. - value: newValue,
  232. - validMsg
  233. - }
  234. - };
  235. - this.setState({
  236. - basicVmSettings
  237. - });
  238. - this.validateWizard(basicVmSettings);
  239. + };
  240. + this.setState({
  241. + basicVmSettings
  242. + });
  243. + this.validateWizard(basicVmSettings);
  244. + };
  245. +
  246. + validateWizard = values => {
  247. + let wizardValid = true;
  248. +
  249. + //check if all required fields are defined
  250. + const requiredKeys = Object.keys(this.basicFormFields).filter(key => this.isFieldRequired(key, values));
  251. + const requiredKeysInValues = Object.keys(values).filter(key => this.isFieldRequired(key, values));
  252. + if (requiredKeys.length !== requiredKeysInValues.length) {
  253. + wizardValid = false;
  254. }
  255. -
  256. - validateWizard = values => {
  257. - let wizardValid = true;
  258.  
  259. - //check if all required fields are defined
  260. - const requiredKeys = Object.keys(this.basicFormFields).filter(key => this.isFieldRequired(key, values));
  261. - const requiredKeysInValues = Object.keys(values).filter(key => this.isFieldRequired(key, values));
  262. - if(requiredKeys.length !== requiredKeysInValues.length){
  263. + //check if all fields are valid
  264. + for (let key in values) {
  265. + if (
  266. + values[key].validMsg &&
  267. + (this.basicFormFields[key].isVisible ? this.basicFormFields[key].isVisible(values) : true)
  268. + ) {
  269. wizardValid = false;
  270. + break;
  271. }
  272. + }
  273.  
  274. - //check if all fields are valid
  275. - for (let key in values) {
  276. - if (values[key].validMsg && (this.basicFormFields[key].isVisible ? this.basicFormFields[key].isVisible(values) : true)) {
  277. - wizardValid = false;
  278. - break;
  279. - }
  280. - }
  281. + this.setState({
  282. + wizardValid
  283. + });
  284. + };
  285.  
  286. - this.setState({
  287. - wizardValid
  288. - });
  289. - }
  290. + isFieldRequired = (key, basicVmSettings) => {
  291. + return (
  292. + this.basicFormFields[key].required &&
  293. + (this.basicFormFields[key].isVisible ? this.basicFormFields[key].isVisible(basicVmSettings) : true)
  294. + );
  295. + };
  296.  
  297. - isFieldRequired = (key, basicVmSettings) => {
  298. - return this.basicFormFields[key].required && (this.basicFormFields[key].isVisible ? this.basicFormFields[key].isVisible(basicVmSettings) : true);
  299. + basicFormFields = {
  300. + name: {
  301. + title: 'Name',
  302. + required: true
  303. + },
  304. + description: {
  305. + title: 'Description',
  306. + type: 'textarea'
  307. + },
  308. + namespace: {
  309. + title: 'Namespace',
  310. + type: 'dropdown',
  311. + default: '--- Select Namespace ---',
  312. + values: this.props.namespaces
  313. + },
  314. + imageSourceType: {
  315. + title: 'Provision Source',
  316. + type: 'dropdown',
  317. + default: '--- Select Provision Source ---',
  318. + values: [
  319. + {
  320. + name: 'PXE'
  321. + },
  322. + {
  323. + name: 'URL'
  324. + },
  325. + {
  326. + name: 'Template'
  327. + },
  328. + {
  329. + name: 'Registry'
  330. + }
  331. + ],
  332. + required: true
  333. + },
  334. + template: {
  335. + title: 'Template',
  336. + type: 'dropdown',
  337. + default: '--- Select Template ---',
  338. + required: true,
  339. + isVisible: basicVmSettings => get(basicVmSettings, 'imageSourceType.value') === 'Template',
  340. + values: this.props.templates
  341. + },
  342. + registryImage: {
  343. + title: 'Registry Image',
  344. + required: true,
  345. + isVisible: basicVmSettings => get(basicVmSettings, 'imageSourceType.value') === 'Registry'
  346. + },
  347. + imageURL: {
  348. + title: 'URL',
  349. + required: true,
  350. + isVisible: basicVmSettings => get(basicVmSettings, 'imageSourceType.value') === 'URL'
  351. + },
  352. + operatingSystem: {
  353. + title: 'Operating System',
  354. + type: 'dropdown',
  355. + default: '--- Select Operating System ---',
  356. + values: this.props.operatingSystems,
  357. + required: true
  358. + },
  359. + flavor: {
  360. + title: 'Flavor',
  361. + type: 'dropdown',
  362. + default: '--- Select Flavor ---',
  363. + values: this.props.flavors.concat([{ name: 'Custom' }]),
  364. + required: true
  365. + },
  366. + memory: {
  367. + title: 'Memory (GB)',
  368. + required: true,
  369. + isVisible: basicVmSettings => get(basicVmSettings, 'flavor.value', '') === 'Custom'
  370. + },
  371. + cpu: {
  372. + title: 'CPUs',
  373. + required: true,
  374. + isVisible: basicVmSettings => get(basicVmSettings, 'flavor.value', '') === 'Custom'
  375. + },
  376. + workloadProfile: {
  377. + title: 'Workload Profile',
  378. + type: 'dropdown',
  379. + default: '--- Select Workload Profile ---',
  380. + values: this.props.workloadProfiles,
  381. + required: true
  382. + },
  383. + startVM: {
  384. + title: 'Start virtual machine on creation',
  385. + type: 'checkbox',
  386. + noBottom: true
  387. + },
  388. + createTemplate: {
  389. + title: 'Create new template from configuration',
  390. + type: 'checkbox',
  391. + noBottom: true
  392. + },
  393. + cloudInit: {
  394. + title: 'Use cloud-init',
  395. + type: 'checkbox'
  396. + },
  397. + hostname: {
  398. + title: 'Hostname',
  399. + isVisible: basicVmSettings => get(basicVmSettings, 'cloudInit.value', false),
  400. + required: true
  401. + },
  402. + authKeys: {
  403. + title: 'Authenticated SSH Keys',
  404. + type: 'textarea',
  405. + isVisible: basicVmSettings => get(basicVmSettings, 'cloudInit.value', false),
  406. + required: true
  407. }
  408. -
  409. - basicFormFields = {
  410. - name: {
  411. - title: 'Name',
  412. - required: true
  413. - },
  414. - description: {
  415. - title: 'Description',
  416. - type: 'textarea'
  417. - },
  418. - namespace: {
  419. - title: 'Namespace',
  420. - type: 'dropdown',
  421. - default: '--- Select Namespace ---',
  422. - values: this.props.namespaces
  423. - },
  424. - imageSourceType: {
  425. - title: 'Provision Source',
  426. - type: 'dropdown',
  427. - default: '--- Select Provision Source ---',
  428. - values: [
  429. - {
  430. - name: 'PXE'
  431. - },
  432. - {
  433. - name: 'URL'
  434. - },
  435. - {
  436. - name: 'Template'
  437. - },
  438. - {
  439. - name: 'Registry'
  440. - }
  441. - ],
  442. - required: true
  443. - },
  444. - template: {
  445. - title: 'Template',
  446. - type: 'dropdown',
  447. - default: '--- Select Template ---',
  448. - required: true,
  449. - isVisible: (basicVmSettings) => get(basicVmSettings, 'imageSourceType.value') === 'Template',
  450. - values: this.props.templates
  451. - },
  452. - registryImage: {
  453. - title: 'Registry Image',
  454. - required: true,
  455. - isVisible: (basicVmSettings) => get(basicVmSettings,'imageSourceType.value') === 'Registry'
  456. - },
  457. - imageURL: {
  458. - title: 'URL',
  459. - required: true,
  460. - isVisible: (basicVmSettings) => get(basicVmSettings,'imageSourceType.value') === 'URL'
  461. - },
  462. - operatingSystem: {
  463. - title: 'Operating System',
  464. - type: 'dropdown',
  465. - default: '--- Select Operating System ---',
  466. - values: this.props.operatingSystems,
  467. - required: true
  468. - },
  469. - flavor:{
  470. - title: 'Flavor',
  471. - type: 'dropdown',
  472. - default: '--- Select Flavor ---',
  473. - values: this.props.flavors.concat([{name:'Custom'}]),
  474. - required: true
  475. - },
  476. - memory:{
  477. - title: 'Memory (GB)',
  478. - required: true,
  479. - isVisible: (basicVmSettings) => get(basicVmSettings, 'flavor.value', '') === 'Custom'
  480. - },
  481. - cpu: {
  482. - title: 'CPUs',
  483. - required: true,
  484. - isVisible: (basicVmSettings) => get(basicVmSettings, 'flavor.value', '') === 'Custom'
  485. - },
  486. - workloadProfile:{
  487. - title: 'Workload Profile',
  488. - type: 'dropdown',
  489. - default: '--- Select Workload Profile ---',
  490. - values: this.props.workloadProfiles,
  491. - required: true
  492. - },
  493. - startVM:{
  494. - title: 'Start virtual machine on creation',
  495. - type: 'checkbox',
  496. - noBottom: true
  497. - },
  498. - createTemplate:{
  499. - title: 'Create new template from configuration',
  500. - type: 'checkbox',
  501. - noBottom: true
  502. - },
  503. - cloudInit:{
  504. - title: 'Use cloud-init',
  505. - type: 'checkbox'
  506. - },
  507. - hostname:{
  508. - title: 'Hostname',
  509. - isVisible: (basicVmSettings) => get(basicVmSettings, 'cloudInit.value', false),
  510. - required: true
  511. - },
  512. - authKeys:{
  513. - title: 'Authenticated SSH Keys',
  514. - type: 'textarea',
  515. - isVisible: (basicVmSettings) => get(basicVmSettings, 'cloudInit.value', false),
  516. - required: true
  517. + };
  518. +
  519. + wizardStepsNewVM = [
  520. + {
  521. + title: 'Basic Settings',
  522. + render: () => (
  523. + <FormFactory
  524. + fields={this.basicFormFields}
  525. + fieldsValues={this.state.basicVmSettings}
  526. + onFormChange={this.onFormChange}
  527. + />
  528. + )
  529. + },
  530. + {
  531. + title: 'Networking',
  532. + render: () => <p>Render</p>
  533. + },
  534. + {
  535. + title: 'Result',
  536. + render: () => {
  537. + createVM(this.state.basicVmSettings, this.state.network, this.state.storage);
  538. + return <p>object visible in console</p>;
  539. }
  540. -
  541. }
  542. -
  543. - wizardStepsNewVM = [
  544. - {
  545. - title: 'Basic Settings',
  546. - render: () => <FormFactory fields={this.basicFormFields} fieldsValues={this.state.basicVmSettings} onFormChange={this.onFormChange}/>
  547. - },
  548. - {
  549. - title: 'Networking',
  550. - render: () => <p>Render</p>
  551. - },
  552. - {
  553. - title: 'Result',
  554. - render: () => {
  555. - createVM(this.state.basicVmSettings, this.state.network, this.state.storage);
  556. - return <p>object visible in console</p>
  557. - }
  558. - }
  559. - ]
  560. + ];
  561.  
  562. - onStepChanged = (index) => {
  563. - this.setState({ activeStepIndex: index })
  564. - }
  565. -
  566. - render() {
  567. - return (
  568. - <Wizard.Pattern
  569. - show
  570. - onHide={this.props.onHide}
  571. - steps={this.wizardStepsNewVM}
  572. - activeStepIndex={this.state.activeStepIndex}
  573. - onStepChanged={index => this.onStepChanged(index)}
  574. - nextStepDisabled={!this.state.wizardValid}
  575. - nextText={this.state.activeStepIndex === 2 ? 'Create Virtual Machine':'Next'}
  576. - />);
  577. - }
  578. -
  579. + onStepChanged = index => {
  580. + this.setState({ activeStepIndex: index });
  581. + };
  582. +
  583. + render() {
  584. + return (
  585. + <Wizard.Pattern
  586. + show
  587. + onHide={this.props.onHide}
  588. + steps={this.wizardStepsNewVM}
  589. + activeStepIndex={this.state.activeStepIndex}
  590. + onStepChanged={index => this.onStepChanged(index)}
  591. + nextStepDisabled={!this.state.wizardValid}
  592. + nextText={this.state.activeStepIndex === 2 ? 'Create Virtual Machine' : 'Next'}
  593. + />
  594. + );
  595. + }
  596. }
  597. diff --git a/src/components/wizards/import-vm/ImportVmWizard.js b/src/components/wizards/import-vm/ImportVmWizard.js
  598. index 1177897..d1ed53f 100644
  599. --- a/src/components/wizards/import-vm/ImportVmWizard.js
  600. +++ b/src/components/wizards/import-vm/ImportVmWizard.js
  601. @@ -3,62 +3,65 @@ import { Wizard } from 'patternfly-react';
  602. import { FormFactory } from '../../forms/FormFactory';
  603.  
  604. export class ImportVmWizard extends React.Component {
  605. + state = {
  606. + activeStepIndex: 0,
  607. + importValues: {}
  608. + };
  609.  
  610. - state = {
  611. - activeStepIndex: 0,
  612. - importValues: {}
  613. + importFields = {
  614. + sourceType: {
  615. + title: 'Import Source Type',
  616. + type: 'dropdown',
  617. + default: '--- Select Import Source ---',
  618. + required: true,
  619. + values: [
  620. + {
  621. + name: 'Foo import source'
  622. + }
  623. + ]
  624. + },
  625. + url: {
  626. + title: 'VMWare URL to EXSi',
  627. + required: true
  628. + },
  629. + username: {
  630. + title: 'VMWare Username',
  631. + required: true
  632. + },
  633. + password: {
  634. + title: 'VMWare Password',
  635. + required: true
  636. }
  637. + };
  638.  
  639. - importFields = {
  640. - sourceType: {
  641. - title: 'Import Source Type',
  642. - type: 'dropdown',
  643. - default: '--- Select Import Source ---',
  644. - required: true,
  645. - values: [
  646. - {
  647. - name: 'Foo import source'
  648. - }
  649. - ]
  650. - },
  651. - url: {
  652. - title: 'VMWare URL to EXSi',
  653. - required: true
  654. - },
  655. - username: {
  656. - title: 'VMWare Username',
  657. - required: true
  658. - },
  659. - password: {
  660. - title: 'VMWare Password',
  661. - required: true
  662. - }
  663. - }
  664. -
  665. - onFormChange = (newValue, target) => {
  666. + onFormChange = (newValue, target) => {};
  667.  
  668. + wizardStepsImportVM = [
  669. + {
  670. + title: 'Basic Information',
  671. + render: () => (
  672. + <FormFactory
  673. + fields={this.importFields}
  674. + fieldsValues={this.state.importValues}
  675. + onFormChange={this.onFormChange}
  676. + />
  677. + )
  678. + },
  679. + {
  680. + title: 'Virtual Machines',
  681. + render: () => <p>Render</p>
  682. }
  683. -
  684. - wizardStepsImportVM = [
  685. - {
  686. - title: 'Basic Information',
  687. - render: () => <FormFactory fields={this.importFields} fieldsValues={this.state.importValues} onFormChange={this.onFormChange} />
  688. - },
  689. - {
  690. - title: 'Virtual Machines',
  691. - render: () => <p>Render</p>
  692. - }
  693. - ]
  694. -
  695. - render() {
  696. - return (
  697. - <Wizard.Pattern
  698. - show
  699. - onHide={this.props.onHide}
  700. - steps={this.wizardStepsImportVM}
  701. - activeStepIndex={this.state.activeStepIndex}
  702. - onStepChanged={index => this.setState({ activeStepIndex: index })}
  703. - />);
  704. - }
  705. -
  706. + ];
  707. +
  708. + render() {
  709. + return (
  710. + <Wizard.Pattern
  711. + show
  712. + onHide={this.props.onHide}
  713. + steps={this.wizardStepsImportVM}
  714. + activeStepIndex={this.state.activeStepIndex}
  715. + onStepChanged={index => this.setState({ activeStepIndex: index })}
  716. + />
  717. + );
  718. + }
  719. }
  720. diff --git a/src/components/wizards/new-vm/NewVmWizard.js b/src/components/wizards/new-vm/NewVmWizard.js
  721. index cdd863b..052f364 100644
  722. --- a/src/components/wizards/new-vm/NewVmWizard.js
  723. +++ b/src/components/wizards/new-vm/NewVmWizard.js
  724. @@ -6,53 +6,54 @@ import { ButtonWithIcon } from '../../buttons/ButtonWithIcon';
  725. import './NewVmWizard.css';
  726.  
  727. export class NewVmWizard extends React.Component {
  728. + state = {
  729. + createVM: false,
  730. + importVM: false
  731. + };
  732.  
  733. - state = {
  734. - createVM: false,
  735. - importVM: false
  736. - }
  737. -
  738. - openCreateVmWizard = () => this.setState({createVM: true});
  739. + openCreateVmWizard = () => this.setState({ createVM: true });
  740. +
  741. + openImportVmWizard = () => this.setState({ importVM: true });
  742.  
  743. - openImportVmWizard = () => this.setState({importVM: true});
  744. -
  745. - render() {
  746. - let wizard;
  747. - if(this.state.createVM) {
  748. - wizard = <CreateVmWizard onHide={this.props.onHide} {...this.props}/>
  749. - } else if(this.state.importVM) {
  750. - wizard = <ImportVmWizard onHide={this.props.onHide} {...this.props}/>
  751. - }
  752. - return (
  753. - <React.Fragment>
  754. - <Wizard show onHide={this.props.onHide}>
  755. - <Wizard.Header title="Create Virtual Machine" onClose={this.props.onHide} />
  756. - <Wizard.Body>
  757. - <Wizard.Row>
  758. - <Wizard.Main>
  759. - <Wizard.Contents stepIndex={0} activeStepIndex={0} className="wizard-content">
  760. - <ButtonWithIcon
  761. - label="Create New Virtual Machine"
  762. - iconType="pf"
  763. - icon="virtual-machine"
  764. - onClick={this.openCreateVmWizard}
  765. - />
  766. - <ButtonWithIcon
  767. - label="Import Existing Virtual Machine"
  768. - iconType="pf"
  769. - icon="import"
  770. - onClick={this.openImportVmWizard}
  771. - />
  772. - </Wizard.Contents>
  773. - </Wizard.Main>
  774. - </Wizard.Row>
  775. - </Wizard.Body>
  776. - <Wizard.Footer>
  777. - <Button bsStyle="default" className="btn-cancel" onClick={this.props.onHide}>Cancel</Button>
  778. - </Wizard.Footer>
  779. - </Wizard>
  780. - {wizard}
  781. - </React.Fragment>
  782. - );
  783. + render() {
  784. + let wizard;
  785. + if (this.state.createVM) {
  786. + wizard = <CreateVmWizard onHide={this.props.onHide} {...this.props} />;
  787. + } else if (this.state.importVM) {
  788. + wizard = <ImportVmWizard onHide={this.props.onHide} {...this.props} />;
  789. }
  790. + return (
  791. + <React.Fragment>
  792. + <Wizard show onHide={this.props.onHide}>
  793. + <Wizard.Header title="Create Virtual Machine" onClose={this.props.onHide} />
  794. + <Wizard.Body>
  795. + <Wizard.Row>
  796. + <Wizard.Main>
  797. + <Wizard.Contents stepIndex={0} activeStepIndex={0} className="wizard-content">
  798. + <ButtonWithIcon
  799. + label="Create New Virtual Machine"
  800. + iconType="pf"
  801. + icon="virtual-machine"
  802. + onClick={this.openCreateVmWizard}
  803. + />
  804. + <ButtonWithIcon
  805. + label="Import Existing Virtual Machine"
  806. + iconType="pf"
  807. + icon="import"
  808. + onClick={this.openImportVmWizard}
  809. + />
  810. + </Wizard.Contents>
  811. + </Wizard.Main>
  812. + </Wizard.Row>
  813. + </Wizard.Body>
  814. + <Wizard.Footer>
  815. + <Button bsStyle="default" className="btn-cancel" onClick={this.props.onHide}>
  816. + Cancel
  817. + </Button>
  818. + </Wizard.Footer>
  819. + </Wizard>
  820. + {wizard}
  821. + </React.Fragment>
  822. + );
  823. + }
  824. }
  825. diff --git a/src/components/wizards/new-vm/NewVmWizard.stories.js b/src/components/wizards/new-vm/NewVmWizard.stories.js
  826. index fec0e1d..037916e 100644
  827. --- a/src/components/wizards/new-vm/NewVmWizard.stories.js
  828. +++ b/src/components/wizards/new-vm/NewVmWizard.stories.js
  829. @@ -5,10 +5,9 @@ import { Button } from 'patternfly-react';
  830. import { os } from './OperatingSystem';
  831.  
  832. class NewVmWizardExample extends React.Component {
  833. -
  834. state = {
  835. show: false
  836. - }
  837. + };
  838.  
  839. storageClasses = [
  840. {
  841. @@ -26,7 +25,7 @@ class NewVmWizardExample extends React.Component {
  842. class: 'storage class 3',
  843. size: 30
  844. }
  845. - ]
  846. + ];
  847.  
  848. namespaces = [
  849. {
  850. @@ -35,7 +34,7 @@ class NewVmWizardExample extends React.Component {
  851. {
  852. name: 'namespace2'
  853. }
  854. - ]
  855. + ];
  856.  
  857. flavors = [
  858. {
  859. @@ -44,7 +43,7 @@ class NewVmWizardExample extends React.Component {
  860. {
  861. name: 'flavor2'
  862. }
  863. - ]
  864. + ];
  865.  
  866. workloadProfiles = [
  867. {
  868. @@ -53,7 +52,7 @@ class NewVmWizardExample extends React.Component {
  869. {
  870. name: 'workloadProfile2'
  871. }
  872. - ]
  873. + ];
  874.  
  875. templates = [
  876. {
  877. @@ -62,33 +61,36 @@ class NewVmWizardExample extends React.Component {
  878. {
  879. name: 'template2'
  880. }
  881. - ]
  882. + ];
  883.  
  884. openWizard = () => {
  885. - this.setState({show: true});
  886. - }
  887. + this.setState({ show: true });
  888. + };
  889.  
  890. onHide = () => {
  891. - this.setState({show: false});
  892. - }
  893. + this.setState({ show: false });
  894. + };
  895.  
  896. render() {
  897. return (
  898. <React.Fragment>
  899. <Button onClick={this.openWizard}>Open New VM Wizard</Button>
  900. - {this.state.show ? <NewVmWizard
  901. + {this.state.show ? (
  902. + <NewVmWizard
  903. onHide={this.onHide}
  904. storageClasses={this.storageClasses}
  905. workloadProfiles={this.workloadProfiles}
  906. flavors={this.flavors}
  907. namespaces={this.namespaces}
  908. - operatingSystems = {os}
  909. - templates={this.templates}/> : undefined }
  910. - </React.Fragment>);
  911. + operatingSystems={os}
  912. + templates={this.templates}
  913. + />
  914. + ) : (
  915. + undefined
  916. + )}
  917. + </React.Fragment>
  918. + );
  919. }
  920. }
  921.  
  922. -storiesOf('Wizards', module)
  923. - .add('New VM Wizard', () => (
  924. - <NewVmWizardExample/>
  925. - ));
  926. +storiesOf('Wizards', module).add('New VM Wizard', () => <NewVmWizardExample />);
  927. diff --git a/src/components/wizards/new-vm/OperatingSystem.js b/src/components/wizards/new-vm/OperatingSystem.js
  928. index 4505c17..5c08eb0 100644
  929. --- a/src/components/wizards/new-vm/OperatingSystem.js
  930. +++ b/src/components/wizards/new-vm/OperatingSystem.js
  931. @@ -1,20 +1,20 @@
  932. export const os = [
  933. - {
  934. - name: 'Alpine Linux 3.5',
  935. - id: 'alpinelinux3.5'
  936. - },
  937. - {
  938. - name: 'Alpine Linux 3.6',
  939. - id: 'alpinelinux3.6'
  940. - },
  941. - {
  942. - name: 'Alpine Linux 3.7',
  943. - id: 'alpinelinux3.7'
  944. - },
  945. - {
  946. - name: 'Mandrake RE Spring 2001',
  947. - id: 'altlinux1.0'
  948. - }
  949. + {
  950. + name: 'Alpine Linux 3.5',
  951. + id: 'alpinelinux3.5'
  952. + },
  953. + {
  954. + name: 'Alpine Linux 3.6',
  955. + id: 'alpinelinux3.6'
  956. + },
  957. + {
  958. + name: 'Alpine Linux 3.7',
  959. + id: 'alpinelinux3.7'
  960. + },
  961. + {
  962. + name: 'Mandrake RE Spring 2001',
  963. + id: 'altlinux1.0'
  964. + }
  965. ];
  966.  
  967. /*
  968. diff --git a/src/constants/index.js b/src/constants/index.js
  969. index 183cca1..09da67f 100644
  970. --- a/src/constants/index.js
  971. +++ b/src/constants/index.js
  972. @@ -1,4 +1,4 @@
  973. -export const API_VERSION='kubevirt.io/v1alpha2'
  974. -export const VM_KIND='VirtualMachine'
  975. -export const OS_LABEL='kubevirt.io/os'
  976. -export const FLAVOR_LABEL='kubevirt.io/flavor'
  977. +export const API_VERSION = 'kubevirt.io/v1alpha2';
  978. +export const VM_KIND = 'VirtualMachine';
  979. +export const OS_LABEL = 'kubevirt.io/os';
  980. +export const FLAVOR_LABEL = 'kubevirt.io/flavor';
  981. diff --git a/src/k8s/request.js b/src/k8s/request.js
  982. index 112a03f..66fee6f 100644
  983. --- a/src/k8s/request.js
  984. +++ b/src/k8s/request.js
  985. @@ -1,47 +1,47 @@
  986. -import { API_VERSION, VM_KIND, OS_LABEL, FLAVOR_LABEL} from '../constants';
  987. +import { API_VERSION, VM_KIND, OS_LABEL, FLAVOR_LABEL } from '../constants';
  988. import { get } from 'lodash';
  989.  
  990. export const createVM = (basicSettings, network, storage) => {
  991. const vm = generateVmJson(basicSettings, network, storage);
  992. -
  993. +
  994. createK8sObject(vm);
  995. -}
  996. +};
  997.  
  998. export const generateVmJson = (basicSettings, network, storage) => {
  999. let vm = {
  1000. apiVersion: API_VERSION,
  1001. kind: VM_KIND,
  1002. - metadata : {
  1003. + metadata: {
  1004. name: basicSettings.name.value,
  1005. labels: {
  1006. [OS_LABEL]: basicSettings.operatingSystem.value
  1007. }
  1008. },
  1009. - spec: {
  1010. - template: {}
  1011. - }
  1012. - }
  1013. + spec: {
  1014. + template: {}
  1015. + }
  1016. + };
  1017.  
  1018. - if(basicSettings.namespace){
  1019. + if (basicSettings.namespace) {
  1020. vm.metadata.namespace = basicSettings.namespace.value;
  1021. }
  1022.  
  1023. - if(basicSettings.description){
  1024. + if (basicSettings.description) {
  1025. vm.metadata.labels.description = basicSettings.description;
  1026. }
  1027. -
  1028. +
  1029. addFlavor(vm, basicSettings);
  1030. addImageSourceType(vm, basicSettings);
  1031. addCloudInit(vm, basicSettings);
  1032.  
  1033. - if(basicSettings.startVM){
  1034. - vm.spec.running=basicSettings.startVM.value;
  1035. + if (basicSettings.startVM) {
  1036. + vm.spec.running = basicSettings.startVM.value;
  1037. }
  1038. return vm;
  1039. -}
  1040. +};
  1041.  
  1042. const addFlavor = (vm, basicSettings) => {
  1043. - if(basicSettings.flavor.value === 'Custom'){
  1044. + if (basicSettings.flavor.value === 'Custom') {
  1045. vm.spec.template.spec = {
  1046. domain: {
  1047. cpu: {
  1048. @@ -53,7 +53,7 @@ const addFlavor = (vm, basicSettings) => {
  1049. }
  1050. }
  1051. }
  1052. - }
  1053. + };
  1054. } else {
  1055. vm.spec.template.spec = {
  1056. metadata: {
  1057. @@ -61,15 +61,15 @@ const addFlavor = (vm, basicSettings) => {
  1058. [FLAVOR_LABEL]: basicSettings.flavor.value
  1059. }
  1060. }
  1061. - }
  1062. + };
  1063. }
  1064. -}
  1065. +};
  1066.  
  1067. const addImageSourceType = (vm, basicSettings) => {
  1068. - if(get(basicSettings.imageSourceType, 'value') === 'Registry'){
  1069. + if (get(basicSettings.imageSourceType, 'value') === 'Registry') {
  1070. let domain = get(vm.spec.template.spec, 'domain', {});
  1071. - let devices = get(domain,'devices',{});
  1072. - let disks = get(devices,'disks',[]);
  1073. + let devices = get(domain, 'devices', {});
  1074. + let disks = get(devices, 'disks', []);
  1075. disks.push({
  1076. name: 'registryvolume',
  1077. volumeName: 'registryvolume',
  1078. @@ -90,12 +90,12 @@ const addImageSourceType = (vm, basicSettings) => {
  1079. });
  1080. vm.spec.template.spec.volumes = volumes;
  1081. }
  1082. -}
  1083. +};
  1084.  
  1085. const addCloudInit = (vm, basicSettings) => {
  1086. - if(get(basicSettings.cloudInit, 'value', false)) {
  1087. + if (get(basicSettings.cloudInit, 'value', false)) {
  1088. let domain = get(vm.spec.template.spec, 'domain', {});
  1089. - let devices = get(domain,'devices',[]);
  1090. + let devices = get(domain, 'devices', []);
  1091. devices.push({
  1092. name: 'cloudinitdisk',
  1093. volumeName: 'cloudinitdisk',
  1094. @@ -109,27 +109,27 @@ const addCloudInit = (vm, basicSettings) => {
  1095. let volumes = get(vm.spec.template.spec, 'volumes', []);
  1096. let userData = '';
  1097. userData = appendToUserData(userData, 'ssh-authorized-keys', basicSettings.authKeys.value);
  1098. - if(get(basicSettings.hostname, 'value')) {
  1099. - userData = appendToUserData(userData, 'hostname',basicSettings.hostname.value)
  1100. + if (get(basicSettings.hostname, 'value')) {
  1101. + userData = appendToUserData(userData, 'hostname', basicSettings.hostname.value);
  1102. }
  1103. volumes.push({
  1104. name: 'cloudinitvolume',
  1105. - cloudInitNoCloud: {
  1106. + cloudInitNoCloud: {
  1107. userData: userData
  1108. }
  1109. });
  1110. vm.spec.template.spec.volumes = volumes;
  1111. }
  1112. -}
  1113. +};
  1114.  
  1115. const appendToUserData = (userData, key, value) => {
  1116. - if(userData !== '') {
  1117. + if (userData !== '') {
  1118. userData += '\n';
  1119. - }
  1120. - userData += `${key}:\n - ${value}`
  1121. + }
  1122. + userData += `${key}:\n - ${value}`;
  1123. return userData;
  1124. -}
  1125. +};
  1126.  
  1127. -export const createK8sObject = (k8sObject) => {
  1128. +export const createK8sObject = k8sObject => {
  1129. console.log(JSON.stringify(k8sObject));
  1130. -}
  1131. +};
  1132. diff --git a/src/k8s/request.test.js b/src/k8s/request.test.js
  1133. index 3df8558..0867f5e 100644
  1134. --- a/src/k8s/request.test.js
  1135. +++ b/src/k8s/request.test.js
  1136. @@ -4,10 +4,10 @@ import { API_VERSION, VM_KIND, OS_LABEL, FLAVOR_LABEL } from '../constants';
  1137.  
  1138. const minimalBasicSettings = {
  1139. name: {
  1140. - value:'name'
  1141. + value: 'name'
  1142. },
  1143. operatingSystem: {
  1144. - value: 'os',
  1145. + value: 'os'
  1146. },
  1147. flavor: {
  1148. value: 'flavor'
  1149. @@ -18,32 +18,32 @@ const minimalBasicSettings = {
  1150. registryImage: {
  1151. value: 'imageURL'
  1152. }
  1153. -}
  1154. +};
  1155.  
  1156. const runAfterCreationSettings = {
  1157. ...minimalBasicSettings,
  1158. startVM: {
  1159. value: true
  1160. }
  1161. -}
  1162. +};
  1163.  
  1164. const customFlavorBasicSettings = {
  1165. ...minimalBasicSettings,
  1166. flavor: {
  1167. value: 'Custom'
  1168. },
  1169. - cpu:{
  1170. + cpu: {
  1171. value: 3
  1172. },
  1173. - memory:{
  1174. + memory: {
  1175. value: 3
  1176. }
  1177. -}
  1178. +};
  1179.  
  1180. const minimalVM = {
  1181. apiVersion: API_VERSION,
  1182. kind: VM_KIND,
  1183. - metadata : {
  1184. + metadata: {
  1185. name: minimalBasicSettings.name.value,
  1186. labels: {
  1187. [OS_LABEL]: minimalBasicSettings.operatingSystem.value
  1188. @@ -57,24 +57,24 @@ const minimalVM = {
  1189. [FLAVOR_LABEL]: minimalBasicSettings.flavor.value
  1190. }
  1191. },
  1192. - domain:{
  1193. - devices:{
  1194. - disks:[
  1195. + domain: {
  1196. + devices: {
  1197. + disks: [
  1198. {
  1199. name: 'registryvolume',
  1200. volumeName: 'registryvolume',
  1201. disk: {
  1202. - bus: 'virtio'
  1203. + bus: 'virtio'
  1204. }
  1205. }
  1206. ]
  1207. }
  1208. },
  1209. - volumes:[
  1210. + volumes: [
  1211. {
  1212. name: 'registryvolume',
  1213. registryDisk: {
  1214. - image: minimalBasicSettings.registryImage.value
  1215. + image: minimalBasicSettings.registryImage.value
  1216. }
  1217. }
  1218. ]
  1219. @@ -85,30 +85,30 @@ const minimalVM = {
  1220.  
  1221. const runAfterCreationVM = {
  1222. ...minimalVM,
  1223. - spec:{
  1224. + spec: {
  1225. ...minimalVM.spec,
  1226. running: true
  1227. }
  1228. -}
  1229. +};
  1230.  
  1231. let customFlavorVM = omit(minimalVM, 'spec.template.spec.metadata');
  1232. customFlavorVM.spec.template.spec.domain.cpu = {
  1233. - cores: customFlavorBasicSettings.cpu.value
  1234. -}
  1235. + cores: customFlavorBasicSettings.cpu.value
  1236. +};
  1237. customFlavorVM.spec.template.spec.domain.resources = {
  1238. requests: {
  1239. memory: `${customFlavorBasicSettings.memory.value}Gi`
  1240. }
  1241. -}
  1242. +};
  1243.  
  1244. describe('Create VM JSON', () => {
  1245. - it('minimal VM JSON', () =>{
  1246. + it('minimal VM JSON', () => {
  1247. expect(request.generateVmJson(minimalBasicSettings)).toEqual(minimalVM);
  1248. });
  1249. - it('with custom flavor', () =>{
  1250. + it('with custom flavor', () => {
  1251. expect(request.generateVmJson(customFlavorBasicSettings)).toEqual(customFlavorVM);
  1252. });
  1253. - it('with running VM', () =>{
  1254. + it('with running VM', () => {
  1255. expect(request.generateVmJson(runAfterCreationSettings)).toEqual(runAfterCreationVM);
  1256. - })
  1257. + });
  1258. });
Add Comment
Please, Sign In to add comment