Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
182 changes: 91 additions & 91 deletions portal-ui/bindata_assetfs.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion portal-ui/src/screens/Console/Console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ const Console = ({
},
{
component: TenantDetails,
path: "/clusters/:clusterName",
path: "/tenants/:tenantName",
},
];
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);
Expand Down
21 changes: 13 additions & 8 deletions portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ const styles = (theme: Theme) =>
...modalBasic,
});

interface Opts {
label: string;
value: string;
}

const AddTenant = ({
open,
closeModalAndRefresh,
Expand All @@ -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();
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -279,7 +284,7 @@ const AddTenant = ({
}}
label="Storage Class"
value={volumeConfiguration.storage_class}
options={storageClassesList}
options={storageClasses}
/>
</Grid>
<Grid item xs={12}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 },
Expand Down
5 changes: 5 additions & 0 deletions portal-ui/src/screens/Console/Tenants/ListTenants/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
export interface IZone {
name: string;
servers: number;
// computed
capacity: string;
volumes: number;
}

export interface IVolumeConfiguration {
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down Expand Up @@ -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 (
Expand Down Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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 && (
Expand All @@ -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}>
Expand All @@ -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"}&nbsp;&nbsp;
Expand All @@ -184,19 +229,9 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
<div>Instances:</div>
<div>{instances}</div>
<div>External KMS:</div>
<div>
{externalKMS ? "Yes" : "No"}&nbsp;&nbsp;
<Button
variant="contained"
color="primary"
size="small"
onClick={() => {}}
>
Edit
</Button>
</div>
<div>Drives:</div>
<div>{drives}</div>
<div>{externalKMS ? "Yes" : "No"}&nbsp;&nbsp;</div>
<div>Volumes:</div>
<div>{volumes}</div>
</div>
</Paper>
<div className={classes.masterActions}>
Expand All @@ -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}>
Expand Down Expand Up @@ -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={{
Expand Down