AWS Marketplace Integration Updates (#1740)
Makes the create tenant for MK AWS updated with new recommendations Fixes Back Link icon alignment and color Adds a helpbox for MK AWS Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -19,43 +19,47 @@ import { Link } from "react-router-dom";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { BackIcon } from "../icons";
|
||||
import { BackSettingsIcon } from "../icons";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
link: {
|
||||
display: "inline-block",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
display: "block",
|
||||
textDecoration: "none",
|
||||
maxWidth: "40px",
|
||||
"&:active": {
|
||||
color: theme.palette.primary.light,
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
marginRight: "11px",
|
||||
iconBox: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
height: "35px",
|
||||
width: "35px",
|
||||
borderRadius: "2px",
|
||||
flexDirection: "row",
|
||||
"&:hover": {
|
||||
background: "rgba(234,237,238)",
|
||||
},
|
||||
"& svg.min-icon": {
|
||||
width: "18px",
|
||||
height: "12px",
|
||||
height: "30px",
|
||||
paddingBottom: 4,
|
||||
paddingTop: 8,
|
||||
paddingRight: 16,
|
||||
paddingLeft: 0,
|
||||
borderRadius: 4,
|
||||
},
|
||||
icon: {
|
||||
lineHeight: 1,
|
||||
marginRight: "14px",
|
||||
alignItems: "center",
|
||||
width: "22px",
|
||||
"& .min-icon": {
|
||||
color: theme.palette.primary.light,
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
},
|
||||
},
|
||||
label: {
|
||||
display: "flex",
|
||||
lineHeight: 1,
|
||||
alignItems: "center",
|
||||
height: "35px",
|
||||
padding: "0 0px 0 5px",
|
||||
fontSize: "18px",
|
||||
paddingTop: 1,
|
||||
fontSize: "14px",
|
||||
fontWeight: 600,
|
||||
color: theme.palette.primary.light,
|
||||
},
|
||||
@@ -92,11 +96,13 @@ const BackLink = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className={classes.icon}>
|
||||
<BackIcon />
|
||||
<div className={classes.iconBox}>
|
||||
<div className={classes.icon}>
|
||||
<BackSettingsIcon />
|
||||
</div>
|
||||
<div className={classes.label}>{label}</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div className={classes.label}>{label}</div>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,12 @@ import {
|
||||
IStorageFactors,
|
||||
} from "./types";
|
||||
import { IPool } from "../screens/Console/Tenants/ListTenants/types";
|
||||
import {
|
||||
IMkEnvs,
|
||||
IntegrationConfiguration,
|
||||
mkPanelConfigurations,
|
||||
} from "../screens/Console/Tenants/AddTenant/Steps/TenantResources/utils";
|
||||
import get from "lodash/get";
|
||||
|
||||
const minStReq = 1073741824; // Minimal Space required for MinIO
|
||||
const minMemReq = 2147483648; // Minimal Memory required for MinIO in bytes
|
||||
@@ -114,12 +120,21 @@ export const k8sScalarUnitsExcluding = (exclude?: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
//getBytes, converts from a value and a unit from units array to bytes
|
||||
//getBytes, converts from a value and a unit from units array to bytes as a string
|
||||
export const getBytes = (
|
||||
value: string,
|
||||
unit: string,
|
||||
fromk8s: boolean = false
|
||||
) => {
|
||||
): string => {
|
||||
return getBytesNumber(value, unit, fromk8s).toString(10);
|
||||
};
|
||||
|
||||
//getBytesNumber, converts from a value and a unit from units array to bytes
|
||||
export const getBytesNumber = (
|
||||
value: string,
|
||||
unit: string,
|
||||
fromk8s: boolean = false
|
||||
): number => {
|
||||
const vl: number = parseFloat(value);
|
||||
|
||||
const unitsTake = fromk8s ? k8sCalcUnits : units;
|
||||
@@ -127,12 +142,12 @@ export const getBytes = (
|
||||
const powFactor = unitsTake.findIndex((element) => element === unit);
|
||||
|
||||
if (powFactor === -1) {
|
||||
return "0";
|
||||
return 0;
|
||||
}
|
||||
const factor = Math.pow(1024, powFactor);
|
||||
const total = vl * factor;
|
||||
|
||||
return total.toString(10);
|
||||
return total;
|
||||
};
|
||||
|
||||
//getTotalSize gets the total size of a value & unit
|
||||
@@ -218,7 +233,9 @@ export const calculateDistribution = (
|
||||
capacityToUse: ICapacity,
|
||||
forcedNodes: number = 0,
|
||||
limitSize: number = 0,
|
||||
drivesPerServer: number = 0
|
||||
drivesPerServer: number = 0,
|
||||
marketplaceIntegration?: IMkEnvs,
|
||||
selectedStorageType?: string
|
||||
): IStorageDistribution => {
|
||||
const requestedSizeBytes = getBytes(
|
||||
capacityToUse.value,
|
||||
@@ -250,7 +267,9 @@ export const calculateDistribution = (
|
||||
requestedSizeBytes,
|
||||
forcedNodes,
|
||||
limitSize,
|
||||
drivesPerServer
|
||||
drivesPerServer,
|
||||
marketplaceIntegration,
|
||||
selectedStorageType
|
||||
);
|
||||
|
||||
return numberOfNodes;
|
||||
@@ -260,7 +279,9 @@ const calculateStorage = (
|
||||
requestedBytes: string,
|
||||
forcedNodes: number,
|
||||
limitSize: number,
|
||||
drivesPerServer: number
|
||||
drivesPerServer: number,
|
||||
marketplaceIntegration?: IMkEnvs,
|
||||
selectedStorageType?: string
|
||||
): IStorageDistribution => {
|
||||
// Size validation
|
||||
const intReqBytes = parseInt(requestedBytes, 10);
|
||||
@@ -272,7 +293,9 @@ const calculateStorage = (
|
||||
intReqBytes,
|
||||
maxDiskSize,
|
||||
limitSize,
|
||||
drivesPerServer
|
||||
drivesPerServer,
|
||||
marketplaceIntegration,
|
||||
selectedStorageType
|
||||
);
|
||||
};
|
||||
|
||||
@@ -281,7 +304,9 @@ const structureCalc = (
|
||||
desiredCapacity: number,
|
||||
maxDiskSize: number,
|
||||
maxClusterSize: number,
|
||||
disksPerNode: number = 0
|
||||
disksPerNode: number = 0,
|
||||
marketplaceIntegration?: IMkEnvs,
|
||||
selectedStorageType?: string
|
||||
): IStorageDistribution => {
|
||||
if (
|
||||
isNaN(nodes) ||
|
||||
@@ -350,6 +375,48 @@ const structureCalc = (
|
||||
pvSize: 0,
|
||||
}; // Cannot allocate this volume size
|
||||
}
|
||||
// validate for integrations
|
||||
if (marketplaceIntegration !== undefined) {
|
||||
const setConfigs = mkPanelConfigurations[marketplaceIntegration];
|
||||
const keyCount = Object.keys(setConfigs).length;
|
||||
|
||||
//Configuration is filled
|
||||
if (keyCount > 0) {
|
||||
const configs: IntegrationConfiguration[] = get(
|
||||
setConfigs,
|
||||
"configurations",
|
||||
[]
|
||||
);
|
||||
const mainSelection = configs.find(
|
||||
(item) => item.typeSelection === selectedStorageType
|
||||
);
|
||||
|
||||
if (mainSelection !== undefined && mainSelection.minimumVolumeSize) {
|
||||
const minimumPvSize = getBytesNumber(
|
||||
mainSelection.minimumVolumeSize?.driveSize,
|
||||
mainSelection.minimumVolumeSize?.sizeUnit,
|
||||
true
|
||||
);
|
||||
const storageTypeLabel = setConfigs.variantSelectorValues!.find(
|
||||
(item) => item.value === selectedStorageType
|
||||
);
|
||||
|
||||
if (persistentVolumeSize < minimumPvSize) {
|
||||
return {
|
||||
error: `For the ${
|
||||
storageTypeLabel!.label
|
||||
} storage type the mininum volume size is ${
|
||||
mainSelection.minimumVolumeSize.driveSize
|
||||
}${mainSelection.minimumVolumeSize.sizeUnit}`,
|
||||
nodes: 0,
|
||||
persistentVolumes: 0,
|
||||
disks: 0,
|
||||
pvSize: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
error: "",
|
||||
|
||||
@@ -55,6 +55,12 @@ import BackLink from "../../../../common/BackLink";
|
||||
import TenantResources from "./Steps/TenantResources/TenantResources";
|
||||
import ConfigLogSearch from "./Steps/ConfigLogSearch";
|
||||
import ConfigPrometheus from "./Steps/ConfigPrometheus";
|
||||
import {
|
||||
IMkEnvs,
|
||||
resourcesConfigurations,
|
||||
} from "./Steps/TenantResources/utils";
|
||||
import HelpBox from "../../../../common/HelpBox";
|
||||
import { StorageIcon } from "../../../../icons";
|
||||
|
||||
interface IAddTenantProps {
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
@@ -66,6 +72,7 @@ interface IAddTenantProps {
|
||||
namespace: string;
|
||||
validPages: string[];
|
||||
classes: any;
|
||||
features?: string[];
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -87,6 +94,7 @@ const AddTenant = ({
|
||||
validPages,
|
||||
setErrorSnackMessage,
|
||||
resetAddTenantForm,
|
||||
features,
|
||||
}: IAddTenantProps) => {
|
||||
// Modals
|
||||
const [showNewCredentials, setShowNewCredentials] = useState<boolean>(false);
|
||||
@@ -95,6 +103,27 @@ const AddTenant = ({
|
||||
|
||||
// Fields
|
||||
const [addSending, setAddSending] = useState<boolean>(false);
|
||||
const [formRender, setFormRender] = useState<IMkEnvs | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let setConfiguration = IMkEnvs.default;
|
||||
|
||||
if (features && features.length !== 0) {
|
||||
const possibleVariables = Object.keys(resourcesConfigurations);
|
||||
|
||||
possibleVariables.forEach((element) => {
|
||||
if (features.includes(element)) {
|
||||
setConfiguration = get(
|
||||
resourcesConfigurations,
|
||||
element,
|
||||
IMkEnvs.default
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setFormRender(setConfiguration);
|
||||
}, [features]);
|
||||
|
||||
/* Send Information to backend */
|
||||
useEffect(() => {
|
||||
@@ -764,20 +793,47 @@ const AddTenant = ({
|
||||
/>
|
||||
)}
|
||||
<PageHeader label={"Create New Tenant"} />
|
||||
<BackLink
|
||||
to={"/tenants"}
|
||||
label={"Tenant List"}
|
||||
executeOnClick={resetAddTenantForm}
|
||||
/>
|
||||
|
||||
<PageLayout>
|
||||
{addSending && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid item xs={12}>
|
||||
<BackLink
|
||||
to={"/tenants"}
|
||||
label={"Tenant List"}
|
||||
executeOnClick={resetAddTenantForm}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.pageBox}>
|
||||
<GenericWizard wizardSteps={filteredWizardSteps} />
|
||||
</Grid>
|
||||
{formRender === IMkEnvs.aws && (
|
||||
<Grid item xs={12} style={{ marginTop: 16 }}>
|
||||
<HelpBox
|
||||
title={"EBS Volume Configuration."}
|
||||
iconComponent={<StorageIcon />}
|
||||
help={
|
||||
<Fragment>
|
||||
<b>Performance Optimized</b>: Uses the <i>gp3</i> EBS storage
|
||||
class class configured at 1,000Mi/s throughput and 16,000
|
||||
IOPS, however the minimum volume size for this type of EBS
|
||||
volume is <b>32Gi</b>.
|
||||
<br />
|
||||
<br />
|
||||
<b>Storage Optimized</b>: Uses the <i>sc1</i> EBS storage
|
||||
class, however the minimum volume size for this type of EBS
|
||||
volume is
|
||||
<b>16Ti</b> to unlock their maximum throughput speed of
|
||||
250Mi/s.
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</PageLayout>
|
||||
</Fragment>
|
||||
);
|
||||
@@ -790,6 +846,7 @@ const mapState = (state: AppState) => ({
|
||||
certificates: state.tenants.createTenant.certificates,
|
||||
selectedStorageClass:
|
||||
state.tenants.createTenant.fields.nameTenant.selectedStorageClass,
|
||||
features: state.console.session.features,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
|
||||
@@ -37,6 +37,7 @@ import { setModalErrorSnackMessage } from "../../../../../../actions";
|
||||
import {
|
||||
isPageValid,
|
||||
setLimitSize,
|
||||
setStorageType,
|
||||
setStorageClassesList,
|
||||
updateAddField,
|
||||
} from "../../../actions";
|
||||
@@ -87,6 +88,8 @@ interface INameTenantMainScreen {
|
||||
selectedStorageClass: string;
|
||||
selectedStorageType: string;
|
||||
formToRender?: IMkEnvs;
|
||||
features?: string[];
|
||||
setStorageType: typeof setStorageType;
|
||||
}
|
||||
|
||||
const NameTenantMain = ({
|
||||
@@ -102,6 +105,8 @@ const NameTenantMain = ({
|
||||
setLimitSize,
|
||||
isPageValid,
|
||||
setModalErrorSnackMessage,
|
||||
features,
|
||||
setStorageType,
|
||||
}: INameTenantMainScreen) => {
|
||||
const [validationErrors, setValidationErrors] = useState<any>({});
|
||||
const [emptyNamespace, setEmptyNamespace] = useState<boolean>(true);
|
||||
@@ -350,10 +355,7 @@ const NameTenantMain = ({
|
||||
id="storage_type"
|
||||
name="storage_type"
|
||||
onChange={(e: SelectChangeEvent<string>) => {
|
||||
updateField(
|
||||
"selectedStorageType",
|
||||
e.target.value as string
|
||||
);
|
||||
setStorageType(e.target.value as string, features);
|
||||
}}
|
||||
label={get(
|
||||
mkPanelConfigurations,
|
||||
@@ -399,6 +401,7 @@ const mapState = (state: AppState) => ({
|
||||
selectedStorageType:
|
||||
state.tenants.createTenant.fields.nameTenant.selectedStorageType,
|
||||
storageClasses: state.tenants.createTenant.storageClasses,
|
||||
features: state.console.session.features,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
@@ -407,6 +410,7 @@ const connector = connect(mapState, {
|
||||
setStorageClassesList,
|
||||
setLimitSize,
|
||||
isPageValid,
|
||||
setStorageType,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(NameTenantMain));
|
||||
|
||||
@@ -45,6 +45,7 @@ import InputBoxWrapper from "../../../../Common/FormComponents/InputBoxWrapper/I
|
||||
import SelectWrapper from "../../../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import TenantSizeResources from "./TenantSizeResources";
|
||||
import InputUnitMenu from "../../../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
|
||||
import { IMkEnvs } from "./utils";
|
||||
|
||||
interface ITenantSizeProps {
|
||||
classes: any;
|
||||
@@ -64,6 +65,8 @@ interface ITenantSizeProps {
|
||||
limitSize: any;
|
||||
selectedStorageClass: string;
|
||||
untouchedECField: boolean;
|
||||
formToRender?: IMkEnvs;
|
||||
selectedStorageType: string;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -106,6 +109,8 @@ const TenantSize = ({
|
||||
limitSize,
|
||||
selectedStorageClass,
|
||||
untouchedECField,
|
||||
formToRender,
|
||||
selectedStorageType,
|
||||
}: ITenantSizeProps) => {
|
||||
const [validationErrors, setValidationErrors] = useState<any>({});
|
||||
const [errorFlag, setErrorFlag] = useState<boolean>(false);
|
||||
@@ -174,7 +179,7 @@ const TenantSize = ({
|
||||
//Validate Cluster Size
|
||||
const size = volumeSize;
|
||||
const factor = sizeFactor;
|
||||
const limitSize = getBytes("12", "Ti", true);
|
||||
const limitSize = getBytes("16", "Ti", true);
|
||||
|
||||
const clusterCapacity: ICapacity = {
|
||||
unit: factor,
|
||||
@@ -185,13 +190,23 @@ const TenantSize = ({
|
||||
clusterCapacity,
|
||||
parseInt(nodes),
|
||||
parseInt(limitSize),
|
||||
parseInt(drivesPerServer)
|
||||
parseInt(drivesPerServer),
|
||||
formToRender,
|
||||
selectedStorageType
|
||||
);
|
||||
|
||||
updateField("distribution", distrCalculate);
|
||||
setErrorFlag(false);
|
||||
setNodeError("");
|
||||
}, [nodes, volumeSize, sizeFactor, updateField, drivesPerServer]);
|
||||
}, [
|
||||
nodes,
|
||||
volumeSize,
|
||||
sizeFactor,
|
||||
updateField,
|
||||
drivesPerServer,
|
||||
selectedStorageType,
|
||||
formToRender,
|
||||
]);
|
||||
|
||||
/*Calculate Allocation End*/
|
||||
|
||||
@@ -406,6 +421,8 @@ const mapState = (state: AppState) => {
|
||||
limitSize: state.tenants.createTenant.limitSize,
|
||||
selectedStorageClass:
|
||||
state.tenants.createTenant.fields.nameTenant.selectedStorageClass,
|
||||
selectedStorageType:
|
||||
state.tenants.createTenant.fields.nameTenant.selectedStorageType,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import React from "react";
|
||||
import { Opts } from "../../../ListTenants/utils";
|
||||
import TenantSizeMK from "./TenantSizeMK";
|
||||
import TenantSize from "./TenantSize";
|
||||
|
||||
export enum IMkEnvs {
|
||||
"aws",
|
||||
@@ -38,11 +39,12 @@ export interface IntegrationConfiguration {
|
||||
memory: number;
|
||||
drivesPerServer: number;
|
||||
driveSize: IDriveSizing;
|
||||
minimumVolumeSize?: IDriveSizing;
|
||||
}
|
||||
|
||||
export const AWSStorageTypes: Opts[] = [
|
||||
{ label: "NVME", value: "nvme" },
|
||||
{ label: "HDD", value: "hdd" },
|
||||
{ label: "Performance Optimized", value: "performance" },
|
||||
{ label: "Capacity Optimized", value: "capacity" },
|
||||
];
|
||||
|
||||
export const AzureStorageTypes: Opts[] = [
|
||||
@@ -59,20 +61,22 @@ export const resourcesConfigurations = {
|
||||
|
||||
export const AWSConfigurations: IntegrationConfiguration[] = [
|
||||
{
|
||||
typeSelection: "nvme",
|
||||
storageClass: "nvme-i3en-12xlarge",
|
||||
CPU: 48,
|
||||
memory: 384,
|
||||
driveSize: { driveSize: "7500", sizeUnit: "Gi" },
|
||||
typeSelection: "performance",
|
||||
storageClass: "performance-c6gn-16xlarge",
|
||||
CPU: 64,
|
||||
memory: 128,
|
||||
driveSize: { driveSize: "32", sizeUnit: "Gi" },
|
||||
drivesPerServer: 4,
|
||||
minimumVolumeSize: { driveSize: "32", sizeUnit: "Gi" },
|
||||
},
|
||||
{
|
||||
typeSelection: "hdd",
|
||||
storageClass: "hdd-d3en-12xlarge",
|
||||
CPU: 8,
|
||||
memory: 32,
|
||||
driveSize: { driveSize: "12.7", sizeUnit: "Ti" },
|
||||
drivesPerServer: 4,
|
||||
typeSelection: "capacity",
|
||||
storageClass: "capacity-c6gn-16xlarge",
|
||||
CPU: 64,
|
||||
memory: 128,
|
||||
driveSize: { driveSize: "16", sizeUnit: "Ti" },
|
||||
drivesPerServer: 18,
|
||||
minimumVolumeSize: { driveSize: "16", sizeUnit: "Ti" },
|
||||
},
|
||||
];
|
||||
|
||||
@@ -132,12 +136,19 @@ export const GCPConfigurations: IntegrationConfiguration[] = [
|
||||
},
|
||||
];
|
||||
|
||||
export const mkPanelConfigurations = {
|
||||
interface mkConfiguration {
|
||||
variantSelectorLabel?: string;
|
||||
variantSelectorValues?: Opts[];
|
||||
configurations?: IntegrationConfiguration[];
|
||||
sizingComponent?: JSX.Element;
|
||||
}
|
||||
|
||||
export const mkPanelConfigurations: { [index: number]: mkConfiguration } = {
|
||||
[IMkEnvs.aws]: {
|
||||
variantSelectorLabel: "Storage Type",
|
||||
variantSelectorValues: AWSStorageTypes,
|
||||
configurations: AWSConfigurations,
|
||||
sizingComponent: <TenantSizeMK formToRender={IMkEnvs.aws} />,
|
||||
sizingComponent: <TenantSize formToRender={IMkEnvs.aws} />,
|
||||
},
|
||||
[IMkEnvs.azure]: {
|
||||
variantSelectorLabel: "VM Size",
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
ADD_TENANT_SET_LIMIT_SIZE,
|
||||
ADD_TENANT_SET_PAGE_VALID,
|
||||
ADD_TENANT_SET_STORAGE_CLASSES_LIST,
|
||||
ADD_TENANT_SET_STORAGE_TYPE,
|
||||
ADD_TENANT_UPDATE_FIELD,
|
||||
TENANT_DETAILS_SET_CURRENT_TENANT,
|
||||
TENANT_DETAILS_SET_LOADING,
|
||||
@@ -84,6 +85,14 @@ export const setStorageClassesList = (storageClasses: Opts[]) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const setStorageType = (storageType: string, features?: string[]) => {
|
||||
return {
|
||||
type: ADD_TENANT_SET_STORAGE_TYPE,
|
||||
storageType,
|
||||
features,
|
||||
};
|
||||
};
|
||||
|
||||
export const setLimitSize = (limitSize: any) => {
|
||||
return {
|
||||
type: ADD_TENANT_SET_LIMIT_SIZE,
|
||||
|
||||
@@ -36,6 +36,7 @@ import {
|
||||
ADD_TENANT_SET_KEY_PAIR_VALUE,
|
||||
ADD_TENANT_SET_LIMIT_SIZE,
|
||||
ADD_TENANT_SET_PAGE_VALID,
|
||||
ADD_TENANT_SET_STORAGE_TYPE,
|
||||
ADD_TENANT_SET_STORAGE_CLASSES_LIST,
|
||||
ADD_TENANT_UPDATE_FIELD,
|
||||
ITenantState,
|
||||
@@ -47,6 +48,7 @@ import {
|
||||
} from "./types";
|
||||
import { KeyPair } from "./ListTenants/utils";
|
||||
import { getRandomString } from "./utils";
|
||||
import { addTenantSetStorageTypeReducer } from "./reducers/add-tenant-reducer";
|
||||
|
||||
const initialState: ITenantState = {
|
||||
createTenant: {
|
||||
@@ -189,9 +191,9 @@ const initialState: ITenantState = {
|
||||
},
|
||||
},
|
||||
tenantSize: {
|
||||
volumeSize: "100",
|
||||
volumeSize: "1024",
|
||||
sizeFactor: "Gi",
|
||||
drivesPerServer: "1",
|
||||
drivesPerServer: "4",
|
||||
nodes: "4",
|
||||
memoryNode: "2",
|
||||
ecParity: "",
|
||||
@@ -401,6 +403,8 @@ export function tenantsReducer(
|
||||
},
|
||||
};
|
||||
return { ...changeCL };
|
||||
case ADD_TENANT_SET_STORAGE_TYPE:
|
||||
return addTenantSetStorageTypeReducer(action, state);
|
||||
case ADD_TENANT_SET_LIMIT_SIZE:
|
||||
const changeSizeLimit = {
|
||||
...state,
|
||||
@@ -739,9 +743,9 @@ export function tenantsReducer(
|
||||
},
|
||||
},
|
||||
tenantSize: {
|
||||
volumeSize: "100",
|
||||
volumeSize: "1024",
|
||||
sizeFactor: "Gi",
|
||||
drivesPerServer: "1",
|
||||
drivesPerServer: "4",
|
||||
nodes: "4",
|
||||
memoryNode: "2",
|
||||
ecParity: "",
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2022 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { ITenantState, SetStorageType } from "../types";
|
||||
import {
|
||||
IMkEnvs,
|
||||
IntegrationConfiguration,
|
||||
mkPanelConfigurations,
|
||||
resourcesConfigurations,
|
||||
} from "../AddTenant/Steps/TenantResources/utils";
|
||||
import get from "lodash/get";
|
||||
import { getBytesNumber } from "../../../../common/utils";
|
||||
|
||||
export const addTenantSetStorageTypeReducer = (
|
||||
action: SetStorageType,
|
||||
state: ITenantState
|
||||
) => {
|
||||
let size = state.createTenant.fields.tenantSize.volumeSize;
|
||||
let sizeFactor = state.createTenant.fields.tenantSize.sizeFactor;
|
||||
let volumeSize = state.createTenant.fields.tenantSize.volumeSize;
|
||||
// for the aws marketplace integration we have some constraints
|
||||
// on the minimum cluster size
|
||||
|
||||
if (action.features !== undefined && action.features.length > 0) {
|
||||
let formToRender = IMkEnvs.default;
|
||||
const possibleVariables = Object.keys(resourcesConfigurations);
|
||||
|
||||
possibleVariables.forEach((element) => {
|
||||
if (action.features !== undefined && action.features.includes(element)) {
|
||||
formToRender = get(resourcesConfigurations, element, IMkEnvs.default);
|
||||
}
|
||||
});
|
||||
|
||||
// if the size is less than the minimum for the selected storage type
|
||||
// we will override the current total storage entered amount with the minimum
|
||||
if (formToRender !== undefined) {
|
||||
const setConfigs = mkPanelConfigurations[formToRender];
|
||||
const keyCount = Object.keys(setConfigs).length;
|
||||
|
||||
//Configuration is filled
|
||||
if (keyCount > 0) {
|
||||
const configs: IntegrationConfiguration[] = get(
|
||||
setConfigs,
|
||||
"configurations",
|
||||
[]
|
||||
);
|
||||
const mainSelection = configs.find(
|
||||
(item) => item.typeSelection === action.storageType
|
||||
);
|
||||
if (mainSelection !== undefined && mainSelection.minimumVolumeSize) {
|
||||
const minimumSize = getBytesNumber(
|
||||
mainSelection.minimumVolumeSize?.driveSize,
|
||||
mainSelection.minimumVolumeSize?.sizeUnit,
|
||||
true
|
||||
);
|
||||
|
||||
const drivesPerServer =
|
||||
state.createTenant.fields.tenantSize.drivesPerServer;
|
||||
const nodes = state.createTenant.fields.tenantSize.drivesPerServer;
|
||||
|
||||
const currentSize = getBytesNumber(size.toString(), sizeFactor, true);
|
||||
if (currentSize < minimumSize) {
|
||||
size = minimumSize.toString(10);
|
||||
const totalSize =
|
||||
parseInt(nodes) *
|
||||
parseInt(drivesPerServer) *
|
||||
parseInt(mainSelection.minimumVolumeSize.driveSize);
|
||||
|
||||
volumeSize = totalSize.toString(10);
|
||||
sizeFactor = mainSelection.minimumVolumeSize.sizeUnit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const newstate = {
|
||||
...state,
|
||||
createTenant: {
|
||||
...state.createTenant,
|
||||
fields: {
|
||||
...state.createTenant.fields,
|
||||
nameTenant: {
|
||||
...state.createTenant.fields.nameTenant,
|
||||
selectedStorageType: action.storageType,
|
||||
},
|
||||
tenantSize: {
|
||||
...state.createTenant.fields.tenantSize,
|
||||
size: size,
|
||||
volumeSize: volumeSize,
|
||||
sizeFactor: sizeFactor,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return { ...newstate };
|
||||
};
|
||||
@@ -34,6 +34,8 @@ export const ADD_TENANT_RESET_FORM = "ADD_TENANT/RESET_FORM";
|
||||
export const ADD_TENANT_SET_STORAGE_CLASSES_LIST =
|
||||
"ADD_TENANT/SET_STORAGE_CLASSES_LIST";
|
||||
export const ADD_TENANT_SET_LIMIT_SIZE = "ADD_TENANT/SET_LIMIT_SIZE";
|
||||
export const ADD_TENANT_SET_STORAGE_TYPE =
|
||||
"ADD_TENANT/ADD_TENANT_SET_STORAGE_TYPE";
|
||||
|
||||
// Security
|
||||
export const ADD_TENANT_ADD_MINIO_KEYPAIR = "ADD_TENANT/ADD_MINIO_KEYPAIR";
|
||||
@@ -390,6 +392,12 @@ interface SetLimitSize {
|
||||
limitSize: any;
|
||||
}
|
||||
|
||||
export interface SetStorageType {
|
||||
type: typeof ADD_TENANT_SET_STORAGE_TYPE;
|
||||
storageType: string;
|
||||
features?: string[];
|
||||
}
|
||||
|
||||
interface AddMinioKeyPair {
|
||||
type: typeof ADD_TENANT_ADD_MINIO_KEYPAIR;
|
||||
}
|
||||
@@ -519,6 +527,7 @@ export type TenantsManagementTypes =
|
||||
| UpdateATField
|
||||
| SetPageValid
|
||||
| SetStorageClassesList
|
||||
| SetStorageType
|
||||
| SetLimitSize
|
||||
| AddMinioKeyPair
|
||||
| DeleteMinioKeyPair
|
||||
|
||||
Reference in New Issue
Block a user