diff --git a/managed/src/main/java/com/yugabyte/yw/controllers/handlers/UniverseCRUDHandler.java b/managed/src/main/java/com/yugabyte/yw/controllers/handlers/UniverseCRUDHandler.java
index d84ef88ec3d8..3641933b345e 100644
--- a/managed/src/main/java/com/yugabyte/yw/controllers/handlers/UniverseCRUDHandler.java
+++ b/managed/src/main/java/com/yugabyte/yw/controllers/handlers/UniverseCRUDHandler.java
@@ -358,7 +358,10 @@ public void configure(Customer customer, UniverseConfigureTaskParams taskParams)
userIntent.masterGFlags = trimFlags(userIntent.masterGFlags);
userIntent.tserverGFlags = trimFlags(userIntent.tserverGFlags);
- if (StringUtils.isEmpty(userIntent.accessKeyCode)) {
+ Provider provider = Provider.getOrBadRequest(UUID.fromString(userIntent.provider));
+ if (StringUtils.isEmpty(userIntent.accessKeyCode)
+ && !(userIntent.providerType.equals(Common.CloudType.onprem)
+ && provider.getDetails().skipProvisioning)) {
userIntent.accessKeyCode = appConfig.getString("yb.security.default.access.key");
}
try {
diff --git a/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderCreateForm.tsx b/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderCreateForm.tsx
index ffd8ec404fbc..6299ecd54b7f 100644
--- a/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderCreateForm.tsx
+++ b/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderCreateForm.tsx
@@ -75,8 +75,14 @@ const VALIDATION_SCHEMA = object().shape({
ACCEPTABLE_CHARS,
'Provider name cannot contain special characters other than "-", and "_"'
),
- sshUser: string().required('SSH user is required.'),
- sshPrivateKeyContent: mixed().required('SSH private key is required.'),
+ sshUser: string().when('skipProvisioning', {
+ is: false,
+ then: string().required('SSH user is required.')
+ }),
+ sshPrivateKeyContent: mixed().when('skipProvisioning', {
+ is: false,
+ then: mixed().required('SSH private key is required.')
+ }),
ntpServers: array().when('ntpSetupType', {
is: NTPSetupType.SPECIFIED,
then: array().of(
diff --git a/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderEditForm.tsx b/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderEditForm.tsx
index a5e22318a0e4..2bd31adb9ce9 100644
--- a/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderEditForm.tsx
+++ b/managed/ui/src/components/configRedesign/providerRedesign/forms/onPrem/OnPremProviderEditForm.tsx
@@ -99,9 +99,12 @@ const VALIDATION_SCHEMA = object().shape({
ACCEPTABLE_CHARS,
'Provider name cannot contain special characters other than "-", and "_"'
),
- sshUser: string().required('SSH user is required.'),
- sshPrivateKeyContent: mixed().when('editSSHKeypair', {
- is: true,
+ sshUser: string().when('skipProvisioning', {
+ is: false,
+ then: string().required('SSH user is required.')
+ }),
+ sshPrivateKeyContent: mixed().when(['editSSHKeypair', 'skipProvisioning'], {
+ is: (editSSHKeypair, skipProvisioning) => editSSHKeypair && !skipProvisioning,
then: mixed().required('SSH private key is required.')
}),
ntpServers: array().when('ntpSetupType', {
diff --git a/managed/ui/src/components/universes/NodeDetails/NodeAction.js b/managed/ui/src/components/universes/NodeDetails/NodeAction.js
index 18f68f012e47..01cef59df4f4 100644
--- a/managed/ui/src/components/universes/NodeDetails/NodeAction.js
+++ b/managed/ui/src/components/universes/NodeDetails/NodeAction.js
@@ -199,7 +199,9 @@ export default class NodeAction extends Component {
disabled,
clusterType,
isKubernetes,
- isOnPremManuallyProvisioned
+ isOnPremManuallyProvisioned,
+ cluster,
+ accessKeys
} = this.props;
const allowedActions =
@@ -363,6 +365,10 @@ export default class NodeAction extends Component {
);
}
+ const accessKeyCode = cluster.userIntent.accessKeyCode;
+ const accessKey = accessKeys.data.find(
+ (key) => key.idKey.providerUUID === providerUUID && key.idKey.keyCode === accessKeyCode
+ );
return (
)}
{isNonEmptyArray(nodeAllowedActions) ? (
diff --git a/managed/ui/src/components/universes/NodeDetails/NodeConnectModal.js b/managed/ui/src/components/universes/NodeDetails/NodeConnectModal.js
index b07878fdae96..1abc5400c991 100644
--- a/managed/ui/src/components/universes/NodeDetails/NodeConnectModal.js
+++ b/managed/ui/src/components/universes/NodeDetails/NodeConnectModal.js
@@ -47,7 +47,8 @@ class NodeConnectModal extends Component {
currentUniverse,
clusterType,
universeUUID,
- providers
+ providers,
+ disabled
} = this.props;
const nodeIPs = { privateIP: currentRow.privateIP, publicIP: currentRow.publicIP };
let accessCommand = null;
@@ -69,7 +70,9 @@ class NodeConnectModal extends Component {
}
const providerUsed = _.find(providers?.data, { uuid: providerUUID });
- const imageBundleUsed = _.find(providerUsed?.imageBundles, { uuid: cluster?.userIntent?.imageBundleUUID });
+ const imageBundleUsed = _.find(providerUsed?.imageBundles, {
+ uuid: cluster?.userIntent?.imageBundleUUID
+ });
const tectiaSSH = runtimeConfigs?.data?.configEntries?.find(
(c) => c.key === 'yb.security.ssh2_enabled'
@@ -107,11 +110,13 @@ class NodeConnectModal extends Component {
const accessKeyInfo = accessKey?.keyInfo;
const sshPort = imageBundleUsed?.details?.sshPort ?? (accessKeyInfo?.sshPort || 22);
if (!isTectiaSSHEnabled) {
- accessCommand = `sudo ssh -i ${accessKeyInfo?.privateKey ?? ''
- } -ostricthostkeychecking=no -p ${sshPort} yugabyte@${nodeIPs.privateIP}`;
+ accessCommand = `sudo ssh -i ${
+ accessKeyInfo?.privateKey ?? ''
+ } -ostricthostkeychecking=no -p ${sshPort} yugabyte@${nodeIPs.privateIP}`;
} else {
- accessCommand = `sshg3 -K ${accessKeyInfo?.privateKey ?? ''
- } -ostricthostkeychecking=no -p ${sshPort} yugabyte@${nodeIPs.privateIP}`;
+ accessCommand = `sshg3 -K ${
+ accessKeyInfo?.privateKey ?? ''
+ } -ostricthostkeychecking=no -p ${sshPort} yugabyte@${nodeIPs.privateIP}`;
}
}
@@ -128,7 +133,8 @@ class NodeConnectModal extends Component {
diff --git a/managed/ui/src/components/universes/NodeDetails/NodeDetails.js b/managed/ui/src/components/universes/NodeDetails/NodeDetails.js
index 8c592f00d546..5d80deb6e320 100644
--- a/managed/ui/src/components/universes/NodeDetails/NodeDetails.js
+++ b/managed/ui/src/components/universes/NodeDetails/NodeDetails.js
@@ -67,7 +67,8 @@ export default class NodeDetails extends Component {
universeMasterInfo
},
customer,
- providers
+ providers,
+ accessKeys
} = this.props;
const universeDetails = currentUniverse.data.universeDetails;
const nodeDetails = universeDetails.nodeDetailsSet;
@@ -220,6 +221,7 @@ export default class NodeDetails extends Component {
customer={customer}
currentUniverse={currentUniverse}
providers={providers}
+ accessKeys={accessKeys}
/>
{readOnlyCluster && (
)}
diff --git a/managed/ui/src/components/universes/NodeDetails/NodeDetailsContainer.js b/managed/ui/src/components/universes/NodeDetails/NodeDetailsContainer.js
index fb72aced0abf..6f76399ec7e6 100644
--- a/managed/ui/src/components/universes/NodeDetails/NodeDetailsContainer.js
+++ b/managed/ui/src/components/universes/NodeDetails/NodeDetailsContainer.js
@@ -21,6 +21,7 @@ import {
function mapStateToProps(state) {
return {
+ accessKeys: state.cloud.accessKeys,
universe: state.universe,
customer: state.customer,
providers: state.cloud.providers
diff --git a/managed/ui/src/components/universes/NodeDetails/NodeDetailsTable.js b/managed/ui/src/components/universes/NodeDetails/NodeDetailsTable.js
index 80c9e684defb..a5752d3613a0 100644
--- a/managed/ui/src/components/universes/NodeDetails/NodeDetailsTable.js
+++ b/managed/ui/src/components/universes/NodeDetails/NodeDetailsTable.js
@@ -61,7 +61,8 @@ export default class NodeDetailsTable extends Component {
currentUniverse,
providers,
isDedicatedNodes,
- isKubernetesCluster
+ isKubernetesCluster,
+ accessKeys
} = this.props;
const successIcon = ;
const warningIcon = ;
@@ -307,6 +308,8 @@ export default class NodeDetailsTable extends Component {
clusterType={clusterType}
isKubernetes={isKubernetes}
isOnPremManuallyProvisioned={isOnPremManuallyProvisioned}
+ cluster={cluster}
+ accessKeys={accessKeys}
/>
);
};
diff --git a/managed/ui/src/redesign/features/universe/universe-form/EditRR.tsx b/managed/ui/src/redesign/features/universe/universe-form/EditRR.tsx
index 6a1b7f7ce5e2..36fdd4e3f93a 100644
--- a/managed/ui/src/redesign/features/universe/universe-form/EditRR.tsx
+++ b/managed/ui/src/redesign/features/universe/universe-form/EditRR.tsx
@@ -34,6 +34,7 @@ import {
UniverseFormData
} from './utils/dto';
import { PROVIDER_FIELD, TOAST_AUTO_DISMISS_INTERVAL } from './utils/constants';
+import { providerQueryKey, api as helperApi } from '../../../helpers/api';
interface EditReadReplicaProps {
uuid: string;
@@ -80,6 +81,15 @@ export const EditReadReplica: FC = ({ uuid, isViewMode })
}
);
+ const asyncProviderUuid = universe?.universeDetails
+ ? getAsyncCluster(universe?.universeDetails)?.userIntent?.provider ?? ''
+ : '';
+ const providerConfigQuery = useQuery(
+ providerQueryKey.detail(asyncProviderUuid),
+ () => helperApi.fetchProvider(asyncProviderUuid),
+ { enabled: !!asyncProviderUuid }
+ );
+
const onCancel = () => browserHistory.push(`/universes/${uuid}`);
const onSubmit = async (formData: UniverseFormData) => {
@@ -127,12 +137,14 @@ export const EditReadReplica: FC = ({ uuid, isViewMode })
} else setK8Modal(true);
};
- if (isLoading || contextState.isLoading) return ;
+ if (isLoading || contextState.isLoading || providerConfigQuery.isLoading) {
+ return ;
+ }
if (!universe?.universeDetails) return null;
//get async form data and intitalize the form
- const initialFormData = getAsyncFormData(universe.universeDetails);
+ const initialFormData = getAsyncFormData(universe.universeDetails, providerConfigQuery.data);
return (
<>
diff --git a/managed/ui/src/redesign/features/universe/universe-form/EditUniverse.tsx b/managed/ui/src/redesign/features/universe/universe-form/EditUniverse.tsx
index 3214a4a2bc93..e39212162bd1 100644
--- a/managed/ui/src/redesign/features/universe/universe-form/EditUniverse.tsx
+++ b/managed/ui/src/redesign/features/universe/universe-form/EditUniverse.tsx
@@ -17,6 +17,7 @@ import { api, QUERY_KEY } from './utils/api';
import { getPlacements } from './form/fields/PlacementsField/PlacementsFieldHelper';
import {
createErrorMessage,
+ getPrimaryCluster,
getPrimaryFormData,
transformTagsArrayToObject,
transitToUniverse
@@ -48,6 +49,7 @@ import {
USER_TAGS_FIELD,
SPOT_INSTANCE_FIELD
} from './utils/constants';
+import { providerQueryKey, api as helperApi } from '../../../helpers/api';
interface EditUniverseProps {
uuid: string;
@@ -101,6 +103,15 @@ export const EditUniverse: FC = ({ uuid, isViewMode }) => {
}
);
+ const primaryProviderUuid = originalData?.universeDetails
+ ? getPrimaryCluster(originalData?.universeDetails)?.userIntent?.provider ?? ''
+ : '';
+ const providerConfigQuery = useQuery(
+ providerQueryKey.detail(primaryProviderUuid),
+ () => helperApi.fetchProvider(primaryProviderUuid),
+ { enabled: !!primaryProviderUuid }
+ );
+
const onCancel = () => browserHistory.push(`/universes/${uuid}`);
const submitEditUniverse = async (finalPayload: UniverseConfigure) => {
@@ -113,9 +124,18 @@ export const EditUniverse: FC = ({ uuid, isViewMode }) => {
}
};
- if (isUniverseLoading || isLoading || !originalData?.universeDetails) return ;
+ if (
+ isUniverseLoading ||
+ isLoading ||
+ !originalData?.universeDetails ||
+ providerConfigQuery.isLoading
+ )
+ return ;
- const initialFormData = getPrimaryFormData(originalData.universeDetails);
+ const initialFormData = getPrimaryFormData(
+ originalData.universeDetails,
+ providerConfigQuery.data
+ );
const onSubmit = async (formData: UniverseFormData) => {
if (!_.isEqual(formData, initialFormData)) {
diff --git a/managed/ui/src/redesign/features/universe/universe-form/form/fields/AccessKeysField/AccessKeysField.tsx b/managed/ui/src/redesign/features/universe/universe-form/form/fields/AccessKeysField/AccessKeysField.tsx
index f1f3094f086d..00c116528a1f 100644
--- a/managed/ui/src/redesign/features/universe/universe-form/form/fields/AccessKeysField/AccessKeysField.tsx
+++ b/managed/ui/src/redesign/features/universe/universe-form/form/fields/AccessKeysField/AccessKeysField.tsx
@@ -8,6 +8,8 @@ import { YBLabel, YBSelectField } from '../../../../../../components';
import { AccessKey, UniverseFormData } from '../../../utils/dto';
import { ACCESS_KEY_FIELD, PROVIDER_FIELD } from '../../../utils/constants';
import { useFormFieldStyles } from '../../../universeMainStyle';
+import { YBProvider } from '../../../../../../../components/configRedesign/providerRedesign/types';
+import { ProviderCode } from '../../../../../../../components/configRedesign/providerRedesign/constants';
const useStyles = makeStyles((theme) => ({
overrideMuiSelectMenu: {
@@ -43,14 +45,20 @@ export const AccessKeysField = ({ disabled }: AccessKeysFieldProps): ReactElemen
const accessKeys = allAccessKeys.data.filter(
(item: AccessKey) => item?.idKey?.providerUUID === provider?.uuid
);
- if (accessKeys?.length)
+ if (accessKeys?.length) {
setValue(ACCESS_KEY_FIELD, accessKeys[0]?.idKey.keyCode, { shouldValidate: true });
+ } else {
+ setValue(ACCESS_KEY_FIELD, null, { shouldValidate: true });
+ }
}, [provider]);
//only first time
useEffectOnce(() => {
- if (accessKeysList?.length && provider?.uuid)
+ if (accessKeysList?.length && provider?.uuid) {
setValue(ACCESS_KEY_FIELD, accessKeysList[0]?.idKey.keyCode, { shouldValidate: true });
+ } else {
+ setValue(ACCESS_KEY_FIELD, null, { shouldValidate: true });
+ }
});
return (
@@ -62,11 +70,12 @@ export const AccessKeysField = ({ disabled }: AccessKeysFieldProps): ReactElemen
;
+export type ProviderMin = Pick & {
+ isOnPremManuallyProvisioned: boolean;
+};
const getOptionLabel = (option: Record): string => option.name;
export const ProvidersField = ({
@@ -32,9 +37,12 @@ export const ProvidersField = ({
onSuccess: (providers) => {
// Pre-select provider by default
if (_.isEmpty(getValues(PROVIDER_FIELD)) && providers.length >= 1) {
+ const provider = providers[0];
+ const isOnPremManuallyProvisioned =
+ provider?.code === ProviderCode.ON_PREM && provider?.details?.skipProvisioning;
setValue(
PROVIDER_FIELD,
- { code: providers[0]?.code, uuid: providers[0]?.uuid },
+ { code: provider?.code, uuid: provider?.uuid, isOnPremManuallyProvisioned },
{ shouldValidate: true }
);
}
@@ -54,7 +62,13 @@ export const ProvidersField = ({
const handleChange = (e: ChangeEvent<{}>, option: any) => {
if (option) {
const { code, uuid } = option;
- setValue(PROVIDER_FIELD, { code, uuid }, { shouldValidate: true });
+ const isOnPremManuallyProvisioned =
+ option?.code === ProviderCode.ON_PREM && option?.details?.skipProvisioning;
+ setValue(
+ PROVIDER_FIELD,
+ { code, uuid, isOnPremManuallyProvisioned },
+ { shouldValidate: true }
+ );
} else {
setValue(PROVIDER_FIELD, DEFAULT_CLOUD_CONFIG.provider, { shouldValidate: true });
}
diff --git a/managed/ui/src/redesign/features/universe/universe-form/form/sections/cloud/CloudConfiguration.tsx b/managed/ui/src/redesign/features/universe/universe-form/form/sections/cloud/CloudConfiguration.tsx
index eff965f313c7..0ec7fd7ad577 100644
--- a/managed/ui/src/redesign/features/universe/universe-form/form/sections/cloud/CloudConfiguration.tsx
+++ b/managed/ui/src/redesign/features/universe/universe-form/form/sections/cloud/CloudConfiguration.tsx
@@ -36,7 +36,7 @@ export const CloudConfiguration = ({ runtimeConfigs }: UniverseFormConfiguration
const { t } = useTranslation();
const isLargeDevice = useMediaQuery('(min-width:1400px)');
- const provider: YBProvider = useWatch({ name: PROVIDER_FIELD });
+ const provider = useWatch({ name: PROVIDER_FIELD });
const providerRuntimeConfigQuery = useQuery(
runtimeConfigQueryKey.providerScope(provider?.uuid),
@@ -111,11 +111,7 @@ export const CloudConfiguration = ({ runtimeConfigs }: UniverseFormConfiguration
-
+
{isPrimary && isGeoPartitionEnabled && (
diff --git a/managed/ui/src/redesign/features/universe/universe-form/utils/helpers.ts b/managed/ui/src/redesign/features/universe/universe-form/utils/helpers.ts
index 96fbc12cd524..b6960ea18f3b 100644
--- a/managed/ui/src/redesign/features/universe/universe-form/utils/helpers.ts
+++ b/managed/ui/src/redesign/features/universe/universe-form/utils/helpers.ts
@@ -35,6 +35,8 @@ import {
MIN_PG_SUPPORTED_PREVIEW_VERSION,
MIN_PG_SUPPORTED_STABLE_VERSION
} from '../../../../helpers/constants';
+import { YBProvider } from '../../../../../components/configRedesign/providerRedesign/types';
+import { ProviderCode } from '../../../../../components/configRedesign/providerRedesign/constants';
export const transitToUniverse = (universeUUID?: string) =>
universeUUID
@@ -60,11 +62,11 @@ export const getCurrentVersion = (universeData: UniverseDetails) => {
export const getUniverseName = (universeData: UniverseDetails) =>
_.get(getClusterByType(universeData, ClusterType.PRIMARY), 'userIntent.universeName');
-export const getPrimaryFormData = (universeData: UniverseDetails) =>
- getFormData(universeData, ClusterType.PRIMARY);
+export const getPrimaryFormData = (universeData: UniverseDetails, providerConfig?: YBProvider) =>
+ getFormData(universeData, ClusterType.PRIMARY, providerConfig);
-export const getAsyncFormData = (universeData: UniverseDetails) =>
- getFormData(universeData, ClusterType.ASYNC);
+export const getAsyncFormData = (universeData: UniverseDetails, providerConfig?: YBProvider) =>
+ getFormData(universeData, ClusterType.ASYNC, providerConfig);
//returns fields needs to be copied from Primary to Async in Create+RR flow
export const getPrimaryInheritedValues = (formData: UniverseFormData) =>
@@ -171,7 +173,11 @@ export const isPGEnabledFromIntent = (intent: UserIntent) => {
};
//Transform universe data to form data
-export const getFormData = (universeData: UniverseDetails, clusterType: ClusterType) => {
+export const getFormData = (
+ universeData: UniverseDetails,
+ clusterType: ClusterType,
+ providerConfig?: YBProvider
+) => {
const { communicationPorts, encryptionAtRestConfig, rootCA } = universeData;
const cluster = getClusterByType(universeData, clusterType);
@@ -184,7 +190,11 @@ export const getFormData = (universeData: UniverseDetails, clusterType: ClusterT
universeName: userIntent.universeName,
provider: {
code: userIntent.providerType,
- uuid: userIntent.provider
+ uuid: userIntent.provider,
+ isOnPremManuallyProvisioned:
+ (providerConfig?.code === ProviderCode.ON_PREM &&
+ providerConfig.details?.skipProvisioning) ??
+ false
},
regionList: userIntent.regionList,
numNodes: userIntent.numNodes,