Skip to content
This repository has been archived by the owner on Apr 28, 2020. It is now read-only.

Commit

Permalink
Fix save vCenter credentials functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
pcbailey committed Jun 7, 2019
1 parent 9db34ed commit 7422a85
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY,
PROVIDER_VMWARE_VCENTER_KEY,
PROVIDER_VMWARE_VM_KEY,
PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_SAVE,
} from '../../providers/VMwareImportProvider/constants';
import { getSimpleV2vVMwareStatus } from '../../../../../utils/status/v2vVMware/v2vVMwareStatus';

Expand All @@ -29,7 +32,7 @@ export const getVmWareInitialState = props => ({
[PROVIDER_VMWARE_CHECK_CONNECTION_KEY]: {
isDisabled: asDisabled(true, PROVIDER_VMWARE_VCENTER_KEY),
},
[PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY]: {},
[PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY]: { value: true },
[PROVIDER_VMWARE_VM_KEY]: {
isDisabled: asDisabled(true, PROVIDER_VMWARE_VM_KEY),
},
Expand All @@ -40,14 +43,16 @@ export const getVmWareInitialState = props => ({

// simple values
[PROVIDER_VMWARE_V2V_NAME_KEY]: null,
[PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY]: null,
[PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY]: PROVIDER_VMWARE_CHECK_CONNECTION_BTN_SAVE,
});

const titleResolver = {
[PROVIDER_VMWARE_VCENTER_KEY]: 'vCenter Instance',
[PROVIDER_VMWARE_HOSTNAME_KEY]: 'vCenter Hostname',
[PROVIDER_VMWARE_USER_NAME_KEY]: 'vCenter User Name',
[PROVIDER_VMWARE_USER_PASSWORD_KEY]: 'vCenter Password',
[PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY]: 'Remember vCenter credentials',
[PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY]: 'Save as New vCenter Instance',
[PROVIDER_VMWARE_VM_KEY]: 'VM to Import',
};

Expand Down Expand Up @@ -75,7 +80,7 @@ const helpResolver = {
[PROVIDER_VMWARE_USER_NAME_KEY]: () => 'User name to be used for connection to a vCenter instance.',
[PROVIDER_VMWARE_USER_PASSWORD_KEY]: () => 'User password to be used for connection to a vCenter instance.',
[PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY]: () =>
'If checked, new secret keeping connection details will be created for later use.',
'If checked, a new secret containing the connection details will be created for future use.',
[PROVIDER_VMWARE_VM_KEY]: () =>
'Select a vCenter virtual machine to import. Loading of their list might take some time. The list will be enabled for selection once data are loaded.',
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { FormRow } from '../../../../Form/FormRow';
import { CONNECT_TO_NEW_INSTANCE } from '../../strings';
import {
PROVIDER_VMWARE,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY,
PROVIDER_VMWARE_CHECK_CONNECTION_KEY,
PROVIDER_VMWARE_HOSTNAME_KEY,
PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY,
Expand Down Expand Up @@ -180,7 +181,7 @@ export class VMWareImportProvider extends React.Component {
disabled={isFieldDisabled(this.getField(PROVIDER_VMWARE_CHECK_CONNECTION_KEY))}
onClick={() => this.onChange(PROVIDER_VMWARE_CHECK_CONNECTION_KEY, true)}
>
Check
{this.getField(PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY)}
</Button>
</FormRow>
<FormRow isHidden={isFieldHidden(this.getField(PROVIDER_VMWARE_STATUS_KEY))}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ export const PROVIDER_VMWARE_USER_PASSWORD_KEY = 'vmwarePassword';
export const PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY = 'rememberVMwareCredentials';

export const PROVIDER_VMWARE_CHECK_CONNECTION_KEY = 'checkConnectionButton';
export const PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY = 'checkConnectionButtonText';
export const PROVIDER_VMWARE_CHECK_CONNECTION_BTN_SAVE = 'Check and Save';
export const PROVIDER_VMWARE_CHECK_CONNECTION_BTN_DONT_SAVE = 'Check';
export const PROVIDER_VMWARE_STATUS_KEY = 'vmwareStatus';

export const PROVIDER_VMWARE_VM_KEY = 'vmwareVm';

export const PROVIDER_VMWARE_V2V_NAME_KEY = 'v2vVmwareName';
export const PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY = 'newVCenterName';
Original file line number Diff line number Diff line change
Expand Up @@ -813,7 +813,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
<FormRow
className="kubevirt-create-vm-wizard__import-vmware-password"
controlSize={5}
help="If checked, new secret keeping connection details will be created for later use."
help="If checked, a new secret containing the connection details will be created for future use."
id={null}
isHidden={false}
isRequired={false}
Expand All @@ -826,7 +826,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
<ValidationFormRow
className="kubevirt-create-vm-wizard__import-vmware-password"
controlSize={5}
help="If checked, new secret keeping connection details will be created for later use."
help="If checked, a new secret containing the connection details will be created for future use."
id={null}
isHidden={false}
isRequired={false}
Expand Down Expand Up @@ -854,7 +854,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
className="text-right col-sm-3"
>
<FormControlLabel
help="If checked, new secret keeping connection details will be created for later use."
help="If checked, a new secret containing the connection details will be created for future use."
isRequired={false}
title=""
>
Expand All @@ -870,7 +870,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
<FieldLevelHelp
buttonClass=""
className="kubevirt-form-group__field-help"
content="If checked, new secret keeping connection details will be created for later use."
content="If checked, a new secret containing the connection details will be created for future use."
placement="right"
rootClose={true}
>
Expand All @@ -882,7 +882,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
id="popover"
placement="right"
>
If checked, new secret keeping connection details will be created for later use.
If checked, a new secret containing the connection details will be created for future use.
</Popover>
}
placement="right"
Expand Down Expand Up @@ -943,7 +943,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
id="vcenter-remember-credentials"
onBlur={[Function]}
onChange={[Function]}
title="Remember vCenter credentials"
title="Save as New vCenter Instance"
>
<Checkbox
bsClass="checkbox"
Expand All @@ -969,7 +969,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
onChange={[Function]}
type="checkbox"
/>
Remember vCenter credentials
Save as New vCenter Instance
</label>
</div>
</Checkbox>
Expand Down Expand Up @@ -1063,9 +1063,7 @@ exports[`<VMWareImportProvider /> renders correctly 1`] = `
id="vcenter-connect"
onClick={[Function]}
type="button"
>
Check
</button>
/>
</Button>
</div>
</Col>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get } from 'lodash';
import { get, has } from 'lodash';

import {
VM_SETTINGS_TAB_KEY,
Expand Down Expand Up @@ -48,6 +48,10 @@ import {
PROVIDER_VMWARE_USER_PASSWORD_KEY,
PROVIDER_VMWARE_VCENTER_KEY,
PROVIDER_VMWARE_VM_KEY,
PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_SAVE,
PROVIDER_VMWARE_CHECK_CONNECTION_BTN_DONT_SAVE,
} from '../../providers/VMwareImportProvider/constants';
import { vmSettingsCreator } from '../vmSettingsTabStateUpdate';
import {
Expand All @@ -57,7 +61,15 @@ import {
import { requestVmDetail } from '../../../../../k8s/requests/v2v/requestVmDetail';
import { prefilUpdateCreator } from './prefillVmStateUpdate';
import { getSimpleV2vVMwareStatus } from '../../../../../utils/status/v2vVMware/v2vVMwareStatus';
import { V2V_WMWARE_STATUS_ALL_OK, V2V_WMWARE_STATUS_UNKNOWN } from '../../../../../utils/status/v2vVMware';
import {
V2V_WMWARE_STATUS_ALL_OK,
V2V_WMWARE_STATUS_CONNECTION_SUCCESSFUL,
V2V_WMWARE_STATUS_UNKNOWN,
} from '../../../../../utils/status/v2vVMware';
import { addLabelToVmwareSecretPatch, removeLabelFromVmwareSecretPatch } from '../../../../../utils';
import { VCENTER_TEMPORARY_LABEL } from '../../../../../constants';
import { SecretModel } from '../../../../../models';
import { getVmwareConnectionName, getVmwareSecretLabels } from '../../../../../selectors/v2v';

const { info, warn, error } = console;

Expand All @@ -84,6 +96,8 @@ export const getVmwareProviderStateUpdate = (prevProps, prevState, props, state,
...[
secretUpdateCreator,
secretValueUpdateCreator,
saveSecretUpdateCreator,
successfulConnectionUpdateCreator,
checkConnectionUpdateCreator,
vmwareNameChangedUpdateCreator,
vmChangedUpdateCreator,
Expand Down Expand Up @@ -236,6 +250,49 @@ export const secretValueUpdateCreator = (prevProps, prevState, props, state, ext
};
};

export const successfulConnectionUpdateCreator = (prevProps, prevState, props, state, extra) => {
const connectionStatus = getVmwareValue(state, PROVIDER_VMWARE_STATUS_KEY);

if (connectionStatus !== V2V_WMWARE_STATUS_CONNECTION_SUCCESSFUL) {
return null;
}

const vCenterName = getVmwareField(state, PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY);
const secret = props.vCenterSecrets.find(s => getName(s) === vCenterName);
const hasTempLabel = has(getVmwareSecretLabels(secret), VCENTER_TEMPORARY_LABEL);
const saveCredentialsRequested = getVmwareValue(state, PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY);

if (saveCredentialsRequested && hasTempLabel) {
const patch = removeLabelFromVmwareSecretPatch(VCENTER_TEMPORARY_LABEL);
props.k8sPatch(SecretModel, secret, patch).catch(err => {
if (!get(err, 'message').includes('Unable to remove nonexistent key')) {
console.error(err); // eslint-disable-line no-console
}
});
}

if (!saveCredentialsRequested && !hasTempLabel) {
const patch = addLabelToVmwareSecretPatch(VCENTER_TEMPORARY_LABEL);
props.k8sPatch(SecretModel, secret, patch).catch(err => console.log(err)); // eslint-disable-line no-console
}

return null;
};

export const saveSecretUpdateCreator = (prevProps, prevState, props, state, extra) => {
if (!hasVmWareSettingsValuesChanged(prevState, state, PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY)) {
return null;
}

const saveCredentialsRequested = getVmwareValue(state, PROVIDER_VMWARE_REMEMBER_PASSWORD_KEY);

return {
[PROVIDER_VMWARE_CHECK_CONNECTION_BTN_TEXT_KEY]: saveCredentialsRequested
? PROVIDER_VMWARE_CHECK_CONNECTION_BTN_SAVE
: PROVIDER_VMWARE_CHECK_CONNECTION_BTN_DONT_SAVE,
};
};

export const checkConnectionUpdateCreator = (prevProps, prevState, props, state, extra) => {
const oldConnect = !!getVmwareValue(prevState, PROVIDER_VMWARE_CHECK_CONNECTION_KEY);
const connect = !!getVmwareValue(state, PROVIDER_VMWARE_CHECK_CONNECTION_KEY);
Expand Down Expand Up @@ -359,6 +416,7 @@ const createConnectionObjects = (props, params, { safeSetState }, afterData) =>
value: getSimpleV2vVMwareStatus(null, { isConnecting: true }),
},
[PROVIDER_VMWARE_V2V_NAME_KEY]: getName(v2vVmware),
[PROVIDER_VMWARE_NEW_VCENTER_NAME_KEY]: getVmwareConnectionName(v2vVmware),
})
)
.catch(err => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ Object {
"vCenterInstance": true,
},
},
"checkConnectionButtonText": "Check",
"rememberVMwareCredentials": Object {
"isDisabled": Object {
"VMWARE_PROVIDER_METADATA_ID": false,
Expand Down
2 changes: 1 addition & 1 deletion src/k8s/requests/v2v/createV2VvmwareObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { buildV2VVMwareObject } from '../../objects/v2v/vmware/vmWareObject';
import { buildVMwareSecret } from '../../objects/v2v/vmware/vmWareSecret';

export const createV2VvmwareObjectWithSecret = async ({ url, username, password, namespace }, { k8sCreate }) => {
const secretName = `temp-${getDefaultSecretName({ url, username })}-`;
const secretName = `${getDefaultSecretName({ url, username })}-`;
const secret = await k8sCreate(
SecretModel,
buildVMwareSecret({
Expand Down
3 changes: 3 additions & 0 deletions src/selectors/v2v/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ export const getLoadedVm = (v2vvmware, vmName) =>
getSimpleV2vVMwareStatus(v2vvmware) === V2V_WMWARE_STATUS_CONNECTION_SUCCESSFUL
? getVms(v2vvmware, []).find(v => v.name === vmName && v.detail && v.detail.raw)
: null;

export const getVmwareSecretLabels = secret => get(secret, 'metadata.labels', {});
export const getVmwareConnectionName = value => get(value, 'spec.connection');
23 changes: 23 additions & 0 deletions src/utils/patches.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,3 +432,26 @@ export const getDeviceBootOrderPatch = (vm, removedDevicePathKey, removedDeviceN

return patches;
};

export const removeLabelFromVmwareSecretPatch = labelKey => {
const patches = [];
const escapedLabel = labelKey.replace('~', '~0').replace('/', '~1');
patches.push({
op: 'remove',
path: `/metadata/labels/${escapedLabel}`,
});

return patches;
};

export const addLabelToVmwareSecretPatch = labelKey => {
const patches = [];
const escapedLabel = labelKey.replace('~', '~0').replace('/', '~1');
patches.push({
op: 'add',
path: `/metadata/labels/${escapedLabel}`,
value: 'true',
});

return patches;
};
24 changes: 24 additions & 0 deletions src/utils/tests/patches.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
TEMPLATE_FLAVOR_LABEL,
POD_NETWORK,
DISK_PATH_KEY,
VCENTER_TEMPORARY_LABEL,
} from '../../constants';
import {
getPxeBootPatch,
Expand All @@ -18,6 +19,8 @@ import {
getStartStopPatch,
getUpdateCpuMemoryPatch,
getDeviceBootOrderPatch,
removeLabelFromVmwareSecretPatch,
addLabelToVmwareSecretPatch,
} from '../patches';
import { cloudInitTestVm } from '../../tests/mocks/vm/cloudInitTestVm.mock';
import { NETWORK_TYPE_POD, NETWORK_TYPE_MULTUS } from '../../components/Wizard/CreateVmWizard/constants';
Expand Down Expand Up @@ -455,6 +458,27 @@ describe('patches.js tests', () => {
expect(patch).toHaveLength(1);
comparePatch(patch[0], '/spec', { running: false });
});

it('removeLabelFromVmwareSecretPatch patch', () => {
const patch = removeLabelFromVmwareSecretPatch(VCENTER_TEMPORARY_LABEL);
expect(patch).toEqual([
{
op: 'remove',
path: '/metadata/labels/kubevirt.io~1temporary',
},
]);
});

it('addLabelToVmwareSecretPatch patch', () => {
const patch = addLabelToVmwareSecretPatch(VCENTER_TEMPORARY_LABEL);
expect(patch).toEqual([
{
op: 'add',
path: '/metadata/labels/kubevirt.io~1temporary',
value: 'true',
},
]);
});
});

describe('getDeviceBootOrderPatch() tests', () => {
Expand Down

0 comments on commit 7422a85

Please sign in to comment.