Просмотр исходного кода

Add `migr_image_map` support to OCI

This could be enabled in backend for other providers as well.
Sergiu Miclea 8 лет назад
Родитель
Сommit
15891cb6e3

+ 14 - 8
src/components/atoms/DropdownButton/index.jsx

@@ -15,7 +15,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 // @flow
 
 import React from 'react'
-import styled from 'styled-components'
+import styled, { css } from 'styled-components'
 
 import arrowImage from './images/arrow.js'
 
@@ -97,15 +97,20 @@ const Wrapper = styled.div`
   cursor: ${props => props.disabled ? 'default' : 'pointer'};
   transition: all ${StyleProps.animations.swift};
   background: ${props => getBackgroundColor(props)};
+  ${props => props.embedded ? css`
+    border: 0;
+    width: calc(100% + 8px);
+    margin-left: -16px;
+  ` : ''}
 
   #dropdown-arrow-image {stroke: ${props => getArrowColor(props)};}
   &:hover {
-    #dropdown-arrow-image {stroke: ${props => props.disabled ? '' : 'white'};}
-    background: ${props => props.disabled ? '' : Palette.primary};
+    #dropdown-arrow-image {stroke: ${props => props.disabled ? '' : props.embedded ? '' : 'white'};}
+    background: ${props => props.disabled ? '' : props.embedded ? '' : Palette.primary};
   }
 
   &:hover ${Label} {
-    color: ${props => props.disabled ? '' : 'white'};
+    color: ${props => props.disabled ? '' : props.embedded ? '' : 'white'};
   }
 `
 const Arrow = styled.div`
@@ -122,6 +127,7 @@ type Props = {
   className?: string,
   disabled?: boolean,
   'data-test-id'?: string,
+  embedded?: boolean,
 }
 class DropdownButton extends React.Component<Props> {
   render() {
@@ -140,15 +146,15 @@ class DropdownButton extends React.Component<Props> {
       >
         <Label
           {...this.props}
-          onClick={() => {}}
-          innerRef={() => {}}
+          onClick={() => { }}
+          innerRef={() => { }}
           data-test-id="dropdownButton-value"
           disabled={this.props.disabled}
         >{this.props.value}</Label>
         <Arrow
           {...this.props}
-          innerRef={() => {}}
-          onClick={() => {}}
+          innerRef={() => { }}
+          onClick={() => { }}
           data-test-id=""
           disabled={this.props.disabled}
           dangerouslySetInnerHTML={{ __html: arrowImage }}

+ 3 - 0
src/components/molecules/Dropdown/index.jsx

@@ -38,6 +38,7 @@ const getWidth = props => {
 }
 const Wrapper = styled.div`
   position: relative;
+  ${props => props.embedded ? 'width: 100%;' : ''}
 `
 const List = styled.div`
   position: absolute;
@@ -111,6 +112,7 @@ type Props = {
   disabled: boolean,
   width: number,
   'data-test-id'?: string,
+  embedded?: boolean,
 }
 type State = {
   showDropdownList: boolean,
@@ -325,6 +327,7 @@ class Dropdown extends React.Component<Props, State> {
         onMouseDown={() => { this.itemMouseDown = true }}
         onMouseUp={() => { this.itemMouseDown = false }}
         data-test-id={this.props['data-test-id'] || 'dropdown'}
+        embedded={this.props.embedded}
       >
         <DropdownButton
           {...this.props}

+ 9 - 2
src/components/molecules/PropertiesTable/index.jsx

@@ -105,9 +105,15 @@ class PropertiesTable extends React.Component<Props> {
       return null
     }
     let items = prop.enum.map(e => {
+      if (typeof e === 'string') {
+        return {
+          label: this.getName(e),
+          value: e,
+        }
+      }
       return {
-        label: this.getName(e),
-        value: e,
+        label: e.name,
+        value: e.id,
       }
     })
 
@@ -120,6 +126,7 @@ class PropertiesTable extends React.Component<Props> {
 
     return (
       <Dropdown
+        embedded
         data-test-id={`${baseId}-dropdown-${prop.name}`}
         width={320}
         noSelectionMessage="Choose a value"

+ 1 - 0
src/components/molecules/PropertiesTable/test.jsx

@@ -26,6 +26,7 @@ let properties = [
   { type: 'strict-boolean', name: 'prop_2', label: 'Strict Boolean', value: false },
   { type: 'string', name: 'prop_3', label: 'String', value: 'value-3' },
   { type: 'string', name: 'prop_3a', label: 'String', required: true, value: 'value-4' },
+  // $FlowIgnore
   { type: 'string', enum: ['a', 'b', 'c'], name: 'prop_4', label: 'String enum', value: 'value-5' },
 ]
 const valueCallback = prop => {

+ 1 - 1
src/components/organisms/WizardOptions/index.jsx

@@ -142,7 +142,7 @@ class WizardOptions extends React.Component<Props> {
     }
 
     let executeNowColumn
-    let fields = fieldsSchema.map((field, i) => {
+    let fields = fieldsSchema.filter(f => f.type !== 'object' || f.properties).map((field, i) => {
       let column = i % 2 === 0 ? 'left' : 'right'
       if (field.name === 'execute_now') {
         executeNowColumn = column

+ 1 - 0
src/components/organisms/WizardOptions/test.jsx

@@ -42,6 +42,7 @@ let fields = [
   {
     name: 'enum_field',
     type: 'string',
+    // $FlowIgnore
     enum: ['enum 1', 'enum 2', 'enum 3'],
   },
   {

+ 8 - 1
src/sources/WizardSource.js

@@ -25,7 +25,7 @@ import type { MainItem } from '../types/MainItem'
 class WizardSourceUtils {
   static getDestinationEnv(data) {
     let env = {}
-    let specialOptions = ['execute_now', 'separate_vm', 'skip_os_morphing'].concat(executionOptions.map(o => o.name))
+    let specialOptions = ['execute_now', 'separate_vm', 'skip_os_morphing', 'windows_image', 'linux_image'].concat(executionOptions.map(o => o.name))
 
     if (data.options) {
       Object.keys(data.options).forEach(optionName => {
@@ -52,6 +52,13 @@ class WizardSourceUtils {
         env.network_map[mapping.sourceNic.network_name] = mapping.targetNetwork.id
       })
     }
+    env.migr_image_map = {}
+    if (data.options && data.options.windows_image) {
+      env.migr_image_map.windows = data.options.windows_image
+    }
+    if (data.options && data.options.linux_image) {
+      env.migr_image_map.linux = data.options.linux_image
+    }
 
     return env
   }

+ 20 - 4
src/stores/ProviderStore.js

@@ -84,10 +84,26 @@ class ProviderStore {
       this.optionsSchema.forEach(field => {
         let fieldValues = options.find(f => f.name === field.name)
         if (fieldValues) {
-          // $FlowIgnore
-          field.enum = [...fieldValues.values]
-          if (fieldValues.config_default) {
-            field.default = typeof fieldValues.config_default === 'string' ? fieldValues.config_default : fieldValues.config_default.id
+          if (field.type === 'string') {
+            // $FlowIgnore
+            field.enum = [...fieldValues.values]
+            if (fieldValues.config_default) {
+              field.default = typeof fieldValues.config_default === 'string' ? fieldValues.config_default : fieldValues.config_default.id
+            }
+            // the `migr_image_map` field is special since it needs to group the values by OS type
+          } else if (field.name === 'migr_image_map') {
+            field.properties = [
+              {
+                name: 'windows_image',
+                type: 'string',
+                enum: fieldValues.values.filter(v => typeof v !== 'string' && v.os_type === 'windows'),
+              },
+              {
+                name: 'linux_image',
+                type: 'string',
+                enum: fieldValues.values.filter(v => typeof v !== 'string' && v.os_type === 'linux'),
+              },
+            ]
           }
         }
       })

+ 3 - 2
src/types/Endpoint.js

@@ -34,6 +34,7 @@ export type Endpoint = {
 
 export type DestinationOption = {
   name: string,
-  values: string[] | {name: string, id: string}[],
-  config_default: string | {name: string, id: string},
+  // $FlowIssue
+  values: string[] | { name: string, id: string, [string]: mixed }[],
+  config_default: string | { name: string, id: string },
 }

+ 2 - 1
src/types/Field.js

@@ -19,7 +19,8 @@ export type Field = {
   type?: string,
   value?: any,
   label?: string,
-  enum?: string[],
+  // $FlowIssue
+  enum?: string[] | { id: string, name: string, [string]: mixed }[],
   default?: any,
   items?: Field[],
   fields?: Field[],

+ 1 - 0
src/utils/LabelDictionary.js

@@ -96,6 +96,7 @@ class LabelDictionary {
     azure: 'Azure',
     vmware_vsphere: 'VMware',
     oci: 'OCI',
+    migr_subnet_id: 'Migration Subnet ID',
     separate_vm: 'Separate Migration/VM?',
     use_replica: 'Use replica',
     windows_migr_image: { label: 'Windows Migration Image', description: 'The Windows Migration Image information found on the Azure page' },