Skip to content

Commit 1dcdc61

Browse files
authored
Fix Tenant Details Bugs (#589)
This fixes #584 by making the expand set a name for the pool This fixes #585 by making the expand set an affinity for the pool This fixes #586 by generating a pool name if it's not indicated only
1 parent 7174892 commit 1dcdc61

File tree

11 files changed

+250
-146
lines changed

11 files changed

+250
-146
lines changed

portal-ui/bindata_assetfs.go

Lines changed: 140 additions & 94 deletions
Large diffs are not rendered by default.

portal-ui/src/common/utils.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,8 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
import storage from "local-storage-fallback";
18-
import {
19-
ICapacity,
20-
IErasureCodeCalc,
21-
IPoolModel,
22-
IStorageFactors,
23-
} from "./types";
18+
import { ICapacity, IErasureCodeCalc, IStorageFactors } from "./types";
19+
import { IPool } from "../screens/Console/Tenants/ListTenants/types";
2420

2521
const minStReq = 1073741824; // Minimal Space required for MinIO
2622
const minMemReq = 2147483648; // Minimal Memory required for MinIO in bytes
@@ -419,7 +415,7 @@ export const erasureCodeCalc = (
419415
};
420416

421417
// Pool Name Generator
422-
export const generatePoolName = (pools: IPoolModel[]) => {
418+
export const generatePoolName = (pools: IPool[]) => {
423419
const poolCounter = pools.length;
424420

425421
return `pool-${poolCounter}`;

portal-ui/src/screens/Console/Menu/Menu.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ const Menu = ({ userLoggedIn, classes, pages, operatorMode }: IMenuProps) => {
187187
});
188188
};
189189

190-
const menuItems = [
190+
let menuItems = [
191191
{
192192
group: "common",
193193
type: "item",
@@ -316,21 +316,34 @@ const Menu = ({ userLoggedIn, classes, pages, operatorMode }: IMenuProps) => {
316316
name: "Warp",
317317
icon: <WarpIcon />,
318318
},
319-
{
320-
group: "License",
321-
type: "item",
322-
component: NavLink,
323-
to: "/license",
324-
name: "License",
325-
icon: <LicenseIcon />,
326-
},
327319
];
328320

329321
const allowedPages = pages.reduce((result: any, item: any, index: any) => {
330322
result[item] = true;
331323
return result;
332324
}, {});
333325

326+
// Append the license page according to the allowedPages
327+
if (allowedPages.hasOwnProperty("/tenants")) {
328+
menuItems.push({
329+
group: "Operator",
330+
type: "item",
331+
component: NavLink,
332+
to: "/license",
333+
name: "License",
334+
icon: <LicenseIcon />,
335+
});
336+
} else {
337+
menuItems.push({
338+
group: "License",
339+
type: "item",
340+
component: NavLink,
341+
to: "/license",
342+
name: "License",
343+
icon: <LicenseIcon />,
344+
});
345+
}
346+
334347
const allowedItems = menuItems.filter(
335348
(item: any) =>
336349
allowedPages[item.to] || item.forceDisplay || item.type !== "item"

portal-ui/src/screens/Console/Menu/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ export const menuGroups = [
1919
{ label: "User", group: "User", collapsible: true },
2020
{ label: "Admin", group: "Admin", collapsible: true },
2121
{ label: "Tools", group: "Tools", collapsible: true },
22-
{ label: "Operator", group: "Operator", collapsible: true },
22+
{ label: "Operator", group: "Operator", collapsible: false },
2323
{ label: "", group: "License", collapsible: false },
2424
];

portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import { IMemorySize } from "./types";
6666
import Divider from "@material-ui/core/Divider";
6767
import { connect } from "react-redux";
6868
import { setModalErrorSnackMessage } from "../../../../actions";
69+
import { getHardcodedAffinity } from "../TenantDetails/utils";
6970

7071
interface IAddTenantProps {
7172
open: boolean;
@@ -917,29 +918,10 @@ const AddTenant = ({
917918
if (addSending) {
918919
const poolName = generatePoolName([]);
919920

920-
const hardCodedAffinity: IAffinityModel = {
921-
podAntiAffinity: {
922-
requiredDuringSchedulingIgnoredDuringExecution: [
923-
{
924-
labelSelector: {
925-
matchExpressions: [
926-
{
927-
key: "v1.min.io/tenant",
928-
operator: "In",
929-
values: [tenantName],
930-
},
931-
{
932-
key: "v1.min.io/pool",
933-
operator: "In",
934-
values: [poolName],
935-
},
936-
],
937-
},
938-
topologyKey: "kubernetes.io/hostname",
939-
},
940-
],
941-
},
942-
};
921+
const hardCodedAffinity: IAffinityModel = getHardcodedAffinity(
922+
tenantName,
923+
poolName
924+
);
943925

944926
const erasureCode = ecParity.split(":")[1];
945927

portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => {
257257
itemActions={tableActions}
258258
columns={[
259259
{ label: "Name", elementKey: "name" },
260+
{ label: "Namespace", elementKey: "namespace" },
260261
{ label: "Capacity", elementKey: "capacity" },
261262
{ label: "# of Pools", elementKey: "pool_count" },
262263
{ label: "State", elementKey: "currentState" },

portal-ui/src/screens/Console/Tenants/ListTenants/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
import { LicenseInfo } from "../../License/types";
18+
import { IAffinityModel } from "../../../../common/types";
1819

1920
export interface IPool {
2021
name: string;
@@ -24,13 +25,15 @@ export interface IPool {
2425
// computed
2526
capacity: string;
2627
volumes: number;
28+
label?: string;
2729
}
2830

2931
export interface IAddPoolRequest {
3032
name: string;
3133
servers: number;
3234
volumes_per_server: number;
3335
volume_configuration: IVolumeConfiguration;
36+
affinity?: IAffinityModel;
3437
}
3538

3639
export interface IVolumeConfiguration {

portal-ui/src/screens/Console/Tenants/TenantDetails/AddPoolModal.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
44
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
55
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
66
import Grid from "@material-ui/core/Grid";
7-
import { niceBytes } from "../../../../common/utils";
7+
import { generatePoolName, niceBytes } from "../../../../common/utils";
88
import { Button, LinearProgress } from "@material-ui/core";
99
import api from "../../../../common/api";
1010
import { IAddPoolRequest, ITenant } from "../ListTenants/types";
11+
import { IAffinityModel } from "../../../../common/types";
12+
import { getHardcodedAffinity } from "./utils";
1113

1214
interface IAddPoolProps {
1315
tenant: ITenant;
@@ -81,16 +83,26 @@ const AddPoolModal = ({
8183
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
8284
e.preventDefault();
8385
setAddSending(true);
86+
87+
const poolName = generatePoolName(tenant.pools);
88+
89+
const hardCodedAffinity: IAffinityModel = getHardcodedAffinity(
90+
tenant.name,
91+
poolName
92+
);
93+
8494
const data: IAddPoolRequest = {
85-
name: "",
95+
name: poolName,
8696
servers: numberOfNodes,
8797
volumes_per_server: volumesPerServer,
8898
volume_configuration: {
8999
size: volumeSize * 1073741824,
90100
storage_class: "",
91101
labels: null,
92102
},
103+
affinity: hardCodedAffinity,
93104
};
105+
94106
api
95107
.invoke(
96108
"POST",

portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ const styles = (theme: Theme) =>
115115
noUnderLine: {
116116
textDecoration: "none",
117117
},
118+
poolLabel: {
119+
color: "#666666",
120+
},
118121
...modalBasic,
119122
...containerForHeader(theme.spacing(4)),
120123
});
@@ -127,7 +130,7 @@ const TenantDetails = ({
127130
const [selectedTab, setSelectedTab] = useState<number>(0);
128131
const [capacity, setCapacity] = useState<number>(0);
129132
const [poolCount, setPoolCount] = useState<number>(0);
130-
const [serverSets, setServerSets] = useState<IPool[]>([]);
133+
const [pools, setPools] = useState<IPool[]>([]);
131134
const [instances, setInstances] = useState<number>(0);
132135
const [volumes, setVolumes] = useState<number>(0);
133136
const [addPoolOpen, setAddPool] = useState<boolean>(false);
@@ -199,25 +202,28 @@ const TenantDetails = ({
199202

200203
let totalInstances = 0;
201204
let totalVolumes = 0;
202-
let count = 1;
205+
let poolNamedIndex = 0;
203206
for (let pool of resPools) {
204207
const cap =
205208
pool.volumes_per_server *
206209
pool.servers *
207210
pool.volume_configuration.size;
208-
pool.name = `pool-${count}`;
211+
pool.label = `pool-${poolNamedIndex}`;
212+
if (pool.name === undefined || pool.name === "") {
213+
pool.name = pool.label;
214+
}
209215
pool.capacity = niceBytes(cap + "");
210216
pool.volumes = pool.servers * pool.volumes_per_server;
211217
totalInstances += pool.servers;
212218
totalVolumes += pool.volumes;
213-
count += 1;
219+
poolNamedIndex += 1;
214220
}
215221
setCapacity(res.total_size);
216222
setPoolCount(resPools.length);
217223
setVolumes(totalVolumes);
218224
setInstances(totalInstances);
219225

220-
setServerSets(resPools);
226+
setPools(resPools);
221227

222228
setTenant(res);
223229
})
@@ -415,7 +421,7 @@ const TenantDetails = ({
415421
{ label: "# of Drives", elementKey: "volumes" },
416422
]}
417423
isLoading={false}
418-
records={serverSets}
424+
records={pools}
419425
entityName="Servers"
420426
idField="name"
421427
/>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2021 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
import { IAffinityModel } from "../../../../common/types";
17+
18+
export const getHardcodedAffinity = (tenantName: string, poolName: string) => {
19+
const hardCodedAffinity: IAffinityModel = {
20+
podAntiAffinity: {
21+
requiredDuringSchedulingIgnoredDuringExecution: [
22+
{
23+
labelSelector: {
24+
matchExpressions: [
25+
{
26+
key: "v1.min.io/tenant",
27+
operator: "In",
28+
values: [tenantName],
29+
},
30+
{
31+
key: "v1.min.io/pool",
32+
operator: "In",
33+
values: [poolName],
34+
},
35+
],
36+
},
37+
topologyKey: "kubernetes.io/hostname",
38+
},
39+
],
40+
},
41+
};
42+
return hardCodedAffinity;
43+
};

0 commit comments

Comments
 (0)