Tenant Details (#162)
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -307,7 +307,7 @@ const Console = ({
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: "/clusters/:clusterName",
|
||||
path: "/tenants/:tenantName",
|
||||
},
|
||||
];
|
||||
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
|
||||
|
||||
@@ -54,6 +54,11 @@ const styles = (theme: Theme) =>
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
interface Opts {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
const AddTenant = ({
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
@@ -75,7 +80,7 @@ const AddTenant = ({
|
||||
const [enableMCS, setEnableMCS] = useState<boolean>(false);
|
||||
const [enableSSL, setEnableSSL] = useState<boolean>(false);
|
||||
const [sizeFactor, setSizeFactor] = useState<string>("Gi");
|
||||
const [storageClasses, setStorageClassesList] = useState<string[]>([]);
|
||||
const [storageClasses, setStorageClassesList] = useState<Opts[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchStorageClassList();
|
||||
@@ -136,18 +141,18 @@ const AddTenant = ({
|
||||
if (res !== null) {
|
||||
classes = res;
|
||||
}
|
||||
setStorageClassesList(classes);
|
||||
setStorageClassesList(
|
||||
classes.map((s: string) => ({
|
||||
label: s,
|
||||
value: s,
|
||||
}))
|
||||
);
|
||||
})
|
||||
.catch((err: any) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const storageClassesList = storageClasses.map((s: string) => ({
|
||||
label: s,
|
||||
value: s,
|
||||
}));
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title="Create Tenant"
|
||||
@@ -279,7 +284,7 @@ const AddTenant = ({
|
||||
}}
|
||||
label="Storage Class"
|
||||
value={volumeConfiguration.storage_class}
|
||||
options={storageClassesList}
|
||||
options={storageClasses}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
|
||||
@@ -76,7 +76,7 @@ const ZonesMultiSelector = ({
|
||||
onChange,
|
||||
classes,
|
||||
}: IZonesMultiSelector) => {
|
||||
const defaultZone: IZone = { name: "", servers: 0 };
|
||||
const defaultZone: IZone = { name: "", servers: 0, capacity: "", volumes: 0 };
|
||||
|
||||
const [currentElements, setCurrentElements] = useState<IZone[]>([
|
||||
{ ...defaultZone },
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
export interface IZone {
|
||||
name: string;
|
||||
servers: number;
|
||||
// computed
|
||||
capacity: string;
|
||||
volumes: number;
|
||||
}
|
||||
|
||||
export interface IVolumeConfiguration {
|
||||
@@ -32,6 +35,8 @@ export interface ITenant {
|
||||
creation_date: Date;
|
||||
volume_size: number;
|
||||
volume_count: number;
|
||||
volumes_per_server: number;
|
||||
zones: IZone[];
|
||||
// computed
|
||||
capacity: string;
|
||||
}
|
||||
|
||||
@@ -5,13 +5,19 @@ import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { factorForDropdown, getTotalSize } from "../../../../common/utils";
|
||||
import {
|
||||
factorForDropdown,
|
||||
getTotalSize,
|
||||
niceBytes,
|
||||
} from "../../../../common/utils";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
|
||||
interface IAddZoneProps {
|
||||
classes: any;
|
||||
open: boolean;
|
||||
onCloseZoneAndReload: (shouldReload: boolean) => void;
|
||||
volumesPerInstance: number;
|
||||
volumeSize: number;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
@@ -60,17 +66,14 @@ const AddZoneModal = ({
|
||||
classes,
|
||||
open,
|
||||
onCloseZoneAndReload,
|
||||
volumesPerInstance,
|
||||
volumeSize,
|
||||
}: IAddZoneProps) => {
|
||||
const [addSending, setAddSending] = useState<boolean>(false);
|
||||
const [zoneName, setZoneName] = useState<string>("");
|
||||
const [numberOfInstances, setNumberOfInstances] = useState<number>(0);
|
||||
const [volumesPerInstance, setVolumesPerInstance] = useState<number>(0);
|
||||
const [sizeFactor, setSizeFactor] = useState<string>("GiB");
|
||||
const [volumeConfiguration, setVolumeConfig] = useState<string>("");
|
||||
const [storageClass, setStorageClass] = useState<string>("");
|
||||
|
||||
const instanceCapacity: number =
|
||||
parseFloat(volumeConfiguration) * volumesPerInstance;
|
||||
const instanceCapacity: number = volumeSize * volumesPerInstance;
|
||||
const totalCapacity: number = instanceCapacity * numberOfInstances;
|
||||
|
||||
return (
|
||||
@@ -112,66 +115,17 @@ const AddZoneModal = ({
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="volumes_per_instance"
|
||||
name="volumes_per_instance"
|
||||
type="number"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setVolumesPerInstance(parseInt(e.target.value));
|
||||
}}
|
||||
label="Volumes per Instance"
|
||||
value={volumesPerInstance.toString(10)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.multiContainer}>
|
||||
<div>
|
||||
<InputBoxWrapper
|
||||
id="volume_size"
|
||||
name="volume_size"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setVolumeConfig(e.target.value);
|
||||
}}
|
||||
label="Size"
|
||||
value={volumeConfiguration}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.sizeFactorContainer}>
|
||||
<SelectWrapper
|
||||
label=""
|
||||
id="size_factor"
|
||||
name="size_factor"
|
||||
value={sizeFactor}
|
||||
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
|
||||
setSizeFactor(e.target.value as string);
|
||||
}}
|
||||
options={factorForDropdown()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="storage_class"
|
||||
name="storage_class"
|
||||
type="string"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setStorageClass(e.target.value);
|
||||
}}
|
||||
label="Volumes per Server"
|
||||
value={storageClass}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.bottomContainer}>
|
||||
<div className={classes.factorElements}>
|
||||
<div>
|
||||
<div className={classes.sizeNumber}>
|
||||
{getTotalSize(instanceCapacity.toString(10), sizeFactor)}
|
||||
{niceBytes(instanceCapacity.toString(10))}
|
||||
</div>
|
||||
<div className={classes.sizeDescription}>Instance Capacity</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className={classes.sizeNumber}>
|
||||
{getTotalSize(totalCapacity.toString(10), sizeFactor)}
|
||||
{niceBytes(totalCapacity.toString(10))}
|
||||
</div>
|
||||
<div className={classes.sizeDescription}>Total Capacity</div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,9 @@ import { niceBytes } from "../../../../common/utils";
|
||||
import AddZoneModal from "./AddZoneModal";
|
||||
import AddBucket from "../../Buckets/ListBuckets/AddBucket";
|
||||
import ReplicationSetup from "./ReplicationSetup";
|
||||
import api from "../../../../common/api";
|
||||
import { BucketInfo } from "../../Buckets/types";
|
||||
import { ITenant, IZone } from "../ListTenants/types";
|
||||
|
||||
interface ITenantDetailsProps {
|
||||
classes: any;
|
||||
@@ -106,12 +109,16 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
const [capacity, setCapacity] = useState<number>(0);
|
||||
const [externalIDP, setExternalIDP] = useState<boolean>(false);
|
||||
const [externalKMS, setExternalKMS] = useState<boolean>(false);
|
||||
const [zones, setZones] = useState<number>(0);
|
||||
const [zoneCount, setZoneCount] = useState<number>(0);
|
||||
const [zones, setZones] = useState<IZone[]>([]);
|
||||
const [instances, setInstances] = useState<number>(0);
|
||||
const [drives, setDrives] = useState<number>(0);
|
||||
const [volumes, setVolumes] = useState<number>(0);
|
||||
const [addZoneOpen, setAddZone] = useState<boolean>(false);
|
||||
const [addBucketOpen, setAddBucketOpen] = useState<boolean>(false);
|
||||
const [addReplicationOpen, setAddReplicationOpen] = useState<boolean>(false);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [tenant, setTenant] = useState<ITenant | null>(null);
|
||||
|
||||
const onCloseZoneAndRefresh = (reload: boolean) => {
|
||||
setAddZone(false);
|
||||
@@ -133,12 +140,50 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
}
|
||||
};
|
||||
|
||||
const loadInfo = () => {
|
||||
const tenantName = match.params["tenantName"];
|
||||
|
||||
setLoading(true);
|
||||
|
||||
api
|
||||
.invoke("GET", `/api/v1/mkube/tenants/${tenantName}`)
|
||||
.then((res: ITenant) => {
|
||||
const total = res.volume_count * res.volume_size;
|
||||
|
||||
setCapacity(total);
|
||||
setZoneCount(res.zone_count);
|
||||
setVolumes(res.volume_count);
|
||||
setInstances(res.instance_count);
|
||||
const resZones = !res.zones ? [] : res.zones;
|
||||
for (let zone of resZones) {
|
||||
zone.volumes = res.volumes_per_server;
|
||||
const cap = res.volumes_per_server * res.volume_size * zone.servers;
|
||||
zone.capacity = niceBytes(cap + "");
|
||||
}
|
||||
setZones(resZones);
|
||||
|
||||
setTenant(res);
|
||||
setError("");
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
setError(err);
|
||||
setLoading(false);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadInfo();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addZoneOpen && (
|
||||
{addZoneOpen && tenant !== null && (
|
||||
<AddZoneModal
|
||||
open={addZoneOpen}
|
||||
onCloseZoneAndReload={onCloseZoneAndRefresh}
|
||||
volumeSize={tenant.volume_size}
|
||||
volumesPerInstance={tenant.volumes_per_server}
|
||||
/>
|
||||
)}
|
||||
{addBucketOpen && (
|
||||
@@ -156,7 +201,7 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6">
|
||||
Tenant > {match.params["clusterName"]}
|
||||
Tenant > {match.params["tenantName"]}
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
@@ -168,7 +213,7 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
<div>Capacity:</div>
|
||||
<div>{niceBytes(capacity.toString(10))}</div>
|
||||
<div>Zones:</div>
|
||||
<div>{zones}</div>
|
||||
<div>{zoneCount}</div>
|
||||
<div>External IDP:</div>
|
||||
<div>
|
||||
{externalIDP ? "Yes" : "No"}
|
||||
@@ -184,19 +229,9 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
<div>Instances:</div>
|
||||
<div>{instances}</div>
|
||||
<div>External KMS:</div>
|
||||
<div>
|
||||
{externalKMS ? "Yes" : "No"}
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
size="small"
|
||||
onClick={() => {}}
|
||||
>
|
||||
Edit
|
||||
</Button>
|
||||
</div>
|
||||
<div>Drives:</div>
|
||||
<div>{drives}</div>
|
||||
<div>{externalKMS ? "Yes" : "No"} </div>
|
||||
<div>Volumes:</div>
|
||||
<div>{volumes}</div>
|
||||
</div>
|
||||
</Paper>
|
||||
<div className={classes.masterActions}>
|
||||
@@ -210,16 +245,6 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
Warp
|
||||
</Button>
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
fullWidth
|
||||
onClick={() => {}}
|
||||
>
|
||||
See as deployment
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
@@ -303,17 +328,13 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
},
|
||||
]}
|
||||
columns={[
|
||||
{
|
||||
label: "Status",
|
||||
elementKey: "status",
|
||||
},
|
||||
{ label: "Name", elementKey: "name" },
|
||||
{ label: "Capacity", elementKey: "capacity" },
|
||||
{ label: "# of Instances", elementKey: "instances" },
|
||||
{ label: "# of Drives", elementKey: "drives" },
|
||||
{ label: "# of Instances", elementKey: "servers" },
|
||||
{ label: "# of Drives", elementKey: "volumes" },
|
||||
]}
|
||||
isLoading={false}
|
||||
records={[]}
|
||||
records={zones}
|
||||
entityName="Zones"
|
||||
idField="name"
|
||||
paginatorConfig={{
|
||||
|
||||
Reference in New Issue
Block a user