+
+
+ {__('Storage')}
+
+
+ {this.renderControllers(controllers)}
+ {hasControllers &&
}
+ {!enableAddControllerBtn ? (
+
+ }
+ className="btn-add-controller"
+ ouiaId="btn-add-controller"
+ isAriaDisabled
+ >
+ {hasControllers
+ ? __('Create another controller')
+ : __('Create controller')}
+
+
+ ) : (
}
className="btn-add-controller"
- onClick={() => addController()}
- disabled={!enableAddControllerBtn}
- bsStyle="primary"
+ ouiaId="btn-add-controller"
+ onClick={addController}
>
- {__('Add Controller')}
+ {hasControllers
+ ? __('Create another controller')
+ : __('Create controller')}
-
-
-
- {this.renderControllers(controllers)}
+ )}
+ `${HARD_DISK_LABEL} ${oneBasedIndex}`;
export const defaultControllerAttributes =
{
@@ -11,7 +13,7 @@ const _defaultDiskAttributes = {
storagePod: '',
thin: false,
eagerZero: false,
- name: __('Hard disk'),
+ name: vmwareDiskNameForIndex(1),
mode: 'persistent',
};
diff --git a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/__snapshots__/vmware.test.js.snap b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/__snapshots__/vmware.test.js.snap
index 243caa84cc..eb17139264 100644
--- a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/__snapshots__/vmware.test.js.snap
+++ b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/__snapshots__/vmware.test.js.snap
@@ -19,7 +19,7 @@ Object {
"eagerZero": false,
"key": "5124c2d1-339b-11e9-98f5-5f761412a4c2",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 1",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -28,9 +28,9 @@ Object {
"controllerKey": 1001,
"datastore": "",
"eagerZero": false,
- "key": "1547e1c0-309a-11e9-98f5-5f761412a4c2",
+ "key": "uuid-2",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 2",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -58,7 +58,7 @@ Object {
"eagerZero": false,
"key": "5124c2d1-339b-11e9-98f5-5f761412a4c2",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 1",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -67,9 +67,9 @@ Object {
"controllerKey": 1000,
"datastore": "",
"eagerZero": false,
- "key": "1547e1c0-309a-11e9-98f5-5f761412a4c2",
+ "key": "uuid-3",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 2",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -91,9 +91,9 @@ Object {
"controllerKey": 1000,
"datastore": "",
"eagerZero": false,
- "key": "1547e1c0-309a-11e9-98f5-5f761412a4c2",
+ "key": "uuid-1",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 1",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -117,7 +117,7 @@ Object {
"eagerZero": false,
"key": "5124c2d1-339b-11e9-98f5-5f761412a4c2",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 1",
"sizeGb": 10,
"storagePod": "",
"thin": false,
@@ -126,9 +126,9 @@ Object {
"controllerKey": 1000,
"datastore": "",
"eagerZero": false,
- "key": "1547e1c0-309a-11e9-98f5-5f761412a4c2",
+ "key": "uuid-4",
"mode": "persistent",
- "name": "Hard disk",
+ "name": "Hard disk 2",
"sizeGb": 10,
"storagePod": "",
"thin": false,
diff --git a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.fixtures.js b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.fixtures.js
index 4b9c982e34..dd846faa71 100644
--- a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.fixtures.js
+++ b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.fixtures.js
@@ -13,7 +13,7 @@ export const diskAttributes = {
datastore: '',
eagerZero: false,
mode: 'persistent',
- name: 'Hard disk',
+ name: 'Hard disk 1',
sizeGb: 10,
storagePod: '',
thin: false,
@@ -36,7 +36,7 @@ const _generateController = key =>
eagerZero: false,
key: diskKey,
mode: 'persistent',
- name: 'Hard disk',
+ name: 'Hard disk 1',
sizeGb: 10,
storagePod: '',
thin: false,
diff --git a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.js b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.js
index 089890ef55..d9d0ca0646 100644
--- a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.js
+++ b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.js
@@ -4,6 +4,10 @@ import { difference, head } from 'lodash';
import Immutable from 'seamless-immutable';
import uuidV1 from 'uuid/v1';
+import {
+ HARD_DISK_LABEL,
+ vmwareDiskNameForIndex,
+} from '../../../actions/hosts/storage/vmware.consts';
import {
VMWARE_CLUSTER_CHANGE,
STORAGE_VMWARE_ADD_CONTROLLER,
@@ -26,6 +30,17 @@ const initialState = Immutable({
volumes: [],
});
+const normalizeDiskName = name => {
+ if (name === HARD_DISK_LABEL) return vmwareDiskNameForIndex(1);
+ return name;
+};
+
+const renumberVolumes = volumes =>
+ volumes.map((vol, idx) => ({
+ ...vol,
+ name: vmwareDiskNameForIndex(idx + 1),
+ }));
+
const availableControllerKeys = Array.from(
{ length: 8 },
(value, index) => 1000 + index
@@ -45,7 +60,6 @@ export default (state = initialState, { type, payload, response }) => {
case STORAGE_VMWARE_ADD_CONTROLLER:
const availableKey = getAvailableKey(state.controllers);
- // controller key is assigned here using getAvailableKey
return state
.update('controllers', ctrls =>
ctrls.concat(
@@ -58,7 +72,8 @@ export default (state = initialState, { type, payload, response }) => {
{},
payload.volume,
{ controllerKey: availableKey },
- { key: uuidV1() }
+ { key: uuidV1() },
+ { name: vmwareDiskNameForIndex(volumes.length + 1) }
)
)
);
@@ -69,6 +84,7 @@ export default (state = initialState, { type, payload, response }) => {
...payload.data,
key: uuidV1(),
controllerKey: payload.controllerKey,
+ name: vmwareDiskNameForIndex(state.volumes.length + 1),
})
);
case STORAGE_VMWARE_REMOVE_CONTROLLER:
@@ -77,8 +93,10 @@ export default (state = initialState, { type, payload, response }) => {
ctrls.filter(ctrl => ctrl.key !== payload.controllerKey)
)
.update('volumes', volumes =>
- volumes.filter(
- volume => volume.controllerKey !== payload.controllerKey
+ renumberVolumes(
+ volumes.filter(
+ volume => volume.controllerKey !== payload.controllerKey
+ )
)
);
case STORAGE_VMWARE_UPDATE_CONTROLLER:
@@ -95,7 +113,7 @@ export default (state = initialState, { type, payload, response }) => {
case STORAGE_VMWARE_REMOVE_DISK:
return state.set(
'volumes',
- state.volumes.filter(v => v.key !== payload.key)
+ renumberVolumes(state.volumes.filter(v => v.key !== payload.key))
);
case STORAGE_VMWARE_INIT:
const newState = {
@@ -107,7 +125,11 @@ export default (state = initialState, { type, payload, response }) => {
storagePods: [],
storagePodsLoading: false,
storagePodsError: undefined,
- volumes: payload.volumes.map(volume => ({ ...volume, key: uuidV1() })),
+ volumes: payload.volumes.map(volume => ({
+ ...volume,
+ key: uuidV1(),
+ name: normalizeDiskName(volume.name),
+ })),
cluster: payload.cluster,
};
return initialState
diff --git a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.test.js b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.test.js
index 80c1faa353..44bf564509 100644
--- a/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.test.js
+++ b/webpack/assets/javascripts/react_app/redux/reducers/hosts/storage/vmware.test.js
@@ -14,7 +14,8 @@ import {
import reducer from './vmware';
jest.mock('uuid/v1');
-uuidV1.mockImplementation(() => '1547e1c0-309a-11e9-98f5-5f761412a4c2');
+let uuidCounter = 0;
+uuidV1.mockImplementation(() => `uuid-${++uuidCounter}`);
describe('vmware storage reducer', () => {
it('returns the initial state', () => {
@@ -80,6 +81,76 @@ describe('vmware storage reducer', () => {
})
).toMatchSnapshot();
});
+
+ it('renumbers volumes after deletion', () => {
+ const stateWith2Disks = reducer(stateWithController, {
+ type: types.STORAGE_VMWARE_ADD_DISK,
+ payload: { controllerKey: 1000, data: diskAttributes },
+ });
+ expect(stateWith2Disks.volumes).toHaveLength(2);
+
+ const stateAfterRemove = reducer(stateWith2Disks, {
+ type: types.STORAGE_VMWARE_REMOVE_DISK,
+ payload: { key: diskKey },
+ });
+ expect(stateAfterRemove.volumes).toHaveLength(1);
+ expect(stateAfterRemove.volumes[0].name).toEqual('Hard disk 1');
+ });
+
+ it('keeps sequential names after removing middle disks', () => {
+ let state = stateWithController;
+
+ state = reducer(state, {
+ type: types.STORAGE_VMWARE_ADD_DISK,
+ payload: { controllerKey: 1000, data: diskAttributes },
+ });
+ state = reducer(state, {
+ type: types.STORAGE_VMWARE_ADD_DISK,
+ payload: { controllerKey: 1000, data: diskAttributes },
+ });
+ state = reducer(state, {
+ type: types.STORAGE_VMWARE_ADD_DISK,
+ payload: { controllerKey: 1000, data: diskAttributes },
+ });
+ expect(state.volumes).toHaveLength(4);
+ expect(state.volumes.map(vol => vol.name)).toEqual([
+ 'Hard disk 1',
+ 'Hard disk 2',
+ 'Hard disk 3',
+ 'Hard disk 4',
+ ]);
+
+ state = reducer(state, {
+ type: types.STORAGE_VMWARE_REMOVE_DISK,
+ payload: { key: state.volumes[1].key },
+ });
+ state = reducer(state, {
+ type: types.STORAGE_VMWARE_REMOVE_DISK,
+ payload: { key: state.volumes[1].key },
+ });
+ expect(state.volumes).toHaveLength(2);
+ expect(state.volumes.map(vol => vol.name)).toEqual([
+ 'Hard disk 1',
+ 'Hard disk 2',
+ ]);
+ });
+ });
+
+ describe('STORAGE_VMWARE_INIT', () => {
+ it('normalizes Hard disk to Hard disk 1 on init', () => {
+ const result = reducer(initialState, {
+ type: types.STORAGE_VMWARE_INIT,
+ payload: {
+ config: { controllerTypes: {} },
+ controllers: [{ type: 'VirtualLsiLogicController', key: 1000 }],
+ volumes: [
+ { name: 'Hard disk', controllerKey: 1000, sizeGb: 10 },
+ ],
+ cluster: 'TestCluster',
+ },
+ });
+ expect(result.volumes[0].name).toEqual('Hard disk 1');
+ });
});
describe('STORAGE_VMWARE_UPDATE_DISK', () => {