Guest User

Untitled

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