Added affinity support to tenant add screen (#706)
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.a19f3d53.chunk.css",
|
||||
"main.js": "/static/js/main.b4a5fae7.chunk.js",
|
||||
"main.js.map": "/static/js/main.b4a5fae7.chunk.js.map",
|
||||
"main.js": "/static/js/main.8671089f.chunk.js",
|
||||
"main.js.map": "/static/js/main.8671089f.chunk.js.map",
|
||||
"runtime-main.js": "/static/js/runtime-main.f48e99e5.js",
|
||||
"runtime-main.js.map": "/static/js/runtime-main.f48e99e5.js.map",
|
||||
"static/css/2.32daf8f7.chunk.css": "/static/css/2.32daf8f7.chunk.css",
|
||||
"static/js/2.e5e999f3.chunk.js": "/static/js/2.e5e999f3.chunk.js",
|
||||
"static/js/2.e5e999f3.chunk.js.map": "/static/js/2.e5e999f3.chunk.js.map",
|
||||
"static/js/2.095198e4.chunk.js": "/static/js/2.095198e4.chunk.js",
|
||||
"static/js/2.095198e4.chunk.js.map": "/static/js/2.095198e4.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/css/2.32daf8f7.chunk.css.map": "/static/css/2.32daf8f7.chunk.css.map",
|
||||
"static/css/main.a19f3d53.chunk.css.map": "/static/css/main.a19f3d53.chunk.css.map",
|
||||
"static/js/2.e5e999f3.chunk.js.LICENSE.txt": "/static/js/2.e5e999f3.chunk.js.LICENSE.txt",
|
||||
"static/js/2.095198e4.chunk.js.LICENSE.txt": "/static/js/2.095198e4.chunk.js.LICENSE.txt",
|
||||
"static/media/minio_console_logo.0837460e.svg": "/static/media/minio_console_logo.0837460e.svg",
|
||||
"static/media/minio_operator_logo.1312b7c9.svg": "/static/media/minio_operator_logo.1312b7c9.svg"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.f48e99e5.js",
|
||||
"static/css/2.32daf8f7.chunk.css",
|
||||
"static/js/2.e5e999f3.chunk.js",
|
||||
"static/js/2.095198e4.chunk.js",
|
||||
"static/css/main.a19f3d53.chunk.css",
|
||||
"static/js/main.b4a5fae7.chunk.js"
|
||||
"static/js/main.8671089f.chunk.js"
|
||||
]
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.32daf8f7.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.e5e999f3.chunk.js"></script><script src="/static/js/main.b4a5fae7.chunk.js"></script></body></html>
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="MinIO Console"/><link href="https://fonts.googleapis.com/css2?family=Lato:wght@400;500;700;900&display=swap" rel="stylesheet"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"/><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png"/><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/><link rel="manifest" href="/manifest.json"/><link rel="mask-icon" href="/safari-pinned-tab.svg" color="#3a4e54"/><title>MinIO Console</title><link href="/static/css/2.32daf8f7.chunk.css" rel="stylesheet"><link href="/static/css/main.a19f3d53.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this["webpackJsonpportal-ui"]=this["webpackJsonpportal-ui"]||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/static/js/2.095198e4.chunk.js"></script><script src="/static/js/main.8671089f.chunk.js"></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
portal-ui/build/static/js/main.8671089f.chunk.js.map
Normal file
1
portal-ui/build/static/js/main.8671089f.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -14,6 +14,8 @@
|
||||
// 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 { ILabelKeyPair } from "../screens/Console/Tenants/types";
|
||||
|
||||
export interface ITenantsObject {
|
||||
tenants: ITenant[];
|
||||
}
|
||||
@@ -70,6 +72,7 @@ export interface ITenantCreator {
|
||||
image_registry?: ImageRegistry;
|
||||
logSearchConfiguration?: LogSearchConfiguration;
|
||||
prometheusConfiguration?: PrometheusConfiguration;
|
||||
affinity?: AffinityConfiguration;
|
||||
}
|
||||
|
||||
export interface ImageRegistry {
|
||||
@@ -95,7 +98,8 @@ export interface ITenantUsage {
|
||||
}
|
||||
|
||||
export interface IAffinityModel {
|
||||
podAntiAffinity: IPodAntiAffinityModel;
|
||||
podAntiAffinity?: IPodAntiAffinityModel;
|
||||
podAffinity?: IPodAffinityModel;
|
||||
}
|
||||
|
||||
export interface IPodAntiAffinityModel {
|
||||
@@ -111,6 +115,19 @@ export interface IPodAffinityTermLabelSelector {
|
||||
matchExpressions: IMatchExpressionItem[];
|
||||
}
|
||||
|
||||
export interface IPodAffinityModel {
|
||||
requiredDuringSchedulingIgnoredDuringExecution: IPodAffinityTerms[];
|
||||
}
|
||||
|
||||
export interface IPodAffinityTerms {
|
||||
labelSelector: IPodAffinityLabelsSelector;
|
||||
topologyKey: string;
|
||||
}
|
||||
|
||||
export interface IPodAffinityLabelsSelector {
|
||||
matchLabels: object;
|
||||
}
|
||||
|
||||
export interface IMatchExpressionItem {
|
||||
key: string;
|
||||
operator: string;
|
||||
@@ -353,3 +370,8 @@ export interface PrometheusConfiguration {
|
||||
storageClass: string;
|
||||
storageSize: number;
|
||||
}
|
||||
|
||||
export interface AffinityConfiguration {
|
||||
affinityType: "default" | "nodeSelector" | "none";
|
||||
nodeSelectorLabels?: ILabelKeyPair[];
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@ import { IAffinityModel, ITenantCreator } from "../../../../common/types";
|
||||
import { KeyPair } from "../ListTenants/utils";
|
||||
|
||||
import { setModalErrorSnackMessage } from "../../../../actions";
|
||||
import { getHardcodedAffinity } from "../TenantDetails/utils";
|
||||
import { getDefaultAffinity, getNodeSelector } from "../TenantDetails/utils";
|
||||
import CredentialsPrompt from "../../Common/CredentialsPrompt/CredentialsPrompt";
|
||||
import NameTenant from "./Steps/NameTenant";
|
||||
import { AppState } from "../../../../store";
|
||||
import { ICertificatesItems, IFieldStore } from "../types";
|
||||
import { ICertificatesItems, IFieldStore, ILabelKeyPair } from "../types";
|
||||
import { updateAddField } from "../actions";
|
||||
import Configure from "./Steps/Configure";
|
||||
import IdentityProvider from "./Steps/IdentityProvider";
|
||||
@@ -46,6 +46,7 @@ import Security from "./Steps/Security";
|
||||
import Encryption from "./Steps/Encryption";
|
||||
import TenantSize from "./Steps/TenantSize";
|
||||
import Preview from "./Steps/Preview";
|
||||
import Affinity from "./Steps/Affinity";
|
||||
|
||||
interface IAddTenantProps {
|
||||
closeAndRefresh: (reloadData: boolean) => any;
|
||||
@@ -162,14 +163,24 @@ const AddTenant = ({
|
||||
const prometheusSelectedStorageClass =
|
||||
fields.configure.prometheusSelectedStorageClass;
|
||||
const prometheusVolumeSize = fields.configure.prometheusVolumeSize;
|
||||
const affinityType = fields.affinity.podAffinity;
|
||||
const affinityLabels = fields.affinity.affinityLabels;
|
||||
|
||||
if (addSending) {
|
||||
const poolName = generatePoolName([]);
|
||||
|
||||
const hardCodedAffinity: IAffinityModel = getHardcodedAffinity(
|
||||
tenantName,
|
||||
poolName
|
||||
);
|
||||
let affinityObject = {};
|
||||
|
||||
switch (affinityType) {
|
||||
case "default":
|
||||
affinityObject = {
|
||||
affinity: getDefaultAffinity(tenantName, poolName),
|
||||
};
|
||||
break;
|
||||
case "nodeSelector":
|
||||
affinityObject = { affinity: getNodeSelector(affinityLabels) };
|
||||
break;
|
||||
}
|
||||
|
||||
const erasureCode = ecParity.split(":")[1];
|
||||
|
||||
@@ -205,7 +216,7 @@ const AddTenant = ({
|
||||
memory: memorySize.limit,
|
||||
},
|
||||
},
|
||||
affinity: hardCodedAffinity,
|
||||
...affinityObject,
|
||||
},
|
||||
],
|
||||
erasureCodingParity: parseInt(erasureCode, 10),
|
||||
@@ -536,6 +547,20 @@ const AddTenant = ({
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Pod Affinity",
|
||||
advancedOnly: true,
|
||||
componentRender: <Affinity />,
|
||||
buttons: [
|
||||
cancelButton,
|
||||
{ label: "Back", type: "back", enabled: true },
|
||||
{
|
||||
label: "Next",
|
||||
type: "next",
|
||||
enabled: validPages.includes("affinity"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Identity Provider",
|
||||
advancedOnly: true,
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 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 React, { useEffect, useState, useCallback, Fragment } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { AppState } from "../../../../../store";
|
||||
import { updateAddField, isPageValid } from "../../actions";
|
||||
import { setModalErrorSnackMessage } from "../../../../../actions";
|
||||
import {
|
||||
modalBasic,
|
||||
wizardCommon,
|
||||
} from "../../../Common/FormComponents/common/styleLibrary";
|
||||
import { Grid } from "@material-ui/core";
|
||||
import {
|
||||
commonFormValidation,
|
||||
IValidation,
|
||||
} from "../../../../../utils/validationFunctions";
|
||||
import RadioGroupSelector from "../../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import QueryMultiSelector from "../../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
|
||||
|
||||
interface IAffinityProps {
|
||||
classes: any;
|
||||
podAffinity: string;
|
||||
affinityLabels: string;
|
||||
setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
|
||||
updateAddField: typeof updateAddField;
|
||||
isPageValid: typeof isPageValid;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
...modalBasic,
|
||||
...wizardCommon,
|
||||
});
|
||||
|
||||
const Affinity = ({
|
||||
classes,
|
||||
podAffinity,
|
||||
affinityLabels,
|
||||
setModalErrorSnackMessage,
|
||||
updateAddField,
|
||||
isPageValid,
|
||||
}: IAffinityProps) => {
|
||||
const [validationErrors, setValidationErrors] = useState<any>({});
|
||||
|
||||
// Common
|
||||
const updateField = useCallback(
|
||||
(field: string, value: any) => {
|
||||
updateAddField("affinity", field, value);
|
||||
},
|
||||
[updateAddField]
|
||||
);
|
||||
|
||||
// Validation
|
||||
useEffect(() => {
|
||||
let customAccountValidation: IValidation[] = [];
|
||||
|
||||
if (podAffinity === "nodeSelector") {
|
||||
let valid = true;
|
||||
|
||||
const splittedLabels = affinityLabels.split("&");
|
||||
|
||||
if (splittedLabels.length === 1 && splittedLabels[0] === "") {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
splittedLabels.forEach((item: string, index: number) => {
|
||||
const splitItem = item.split("=");
|
||||
|
||||
if (splitItem.length !== 2) {
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (index + 1 !== splittedLabels.length) {
|
||||
if (splitItem[0] === "" || splitItem[1] === "") {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
customAccountValidation = [
|
||||
...customAccountValidation,
|
||||
{
|
||||
fieldKey: "labels",
|
||||
required: true,
|
||||
value: affinityLabels,
|
||||
customValidation: !valid,
|
||||
customValidationMessage:
|
||||
"You need to add at least one label key-pair",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const commonVal = commonFormValidation(customAccountValidation);
|
||||
|
||||
isPageValid("affinity", Object.keys(commonVal).length === 0);
|
||||
|
||||
setValidationErrors(commonVal);
|
||||
}, [isPageValid, podAffinity, affinityLabels]);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<div className={classes.headerElement}>
|
||||
<h3 className={classes.h3Section}>Pod Affinity</h3>
|
||||
<span className={classes.descriptionText}>
|
||||
Configure how pods will be assigned to nodes
|
||||
</span>
|
||||
</div>
|
||||
<Grid item xs={12}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={podAffinity}
|
||||
id="affinity-options"
|
||||
name="affinity-options"
|
||||
label="Type"
|
||||
onChange={(e) => {
|
||||
updateField("podAffinity", e.target.value);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ label: "None", value: "none" },
|
||||
{ label: "Default (Pod Anti-afinnity)", value: "default" },
|
||||
{ label: "Node Selector", value: "nodeSelector" },
|
||||
]}
|
||||
/>
|
||||
MinIO supports multiple configurations for Pod Afinnity
|
||||
</Grid>
|
||||
{podAffinity === "nodeSelector" && (
|
||||
<Fragment>
|
||||
<br />
|
||||
<Grid item xs={12}>
|
||||
<QueryMultiSelector
|
||||
name="labels"
|
||||
label="Labels"
|
||||
elements={affinityLabels}
|
||||
onChange={(vl: string) => {
|
||||
updateField("affinityLabels", vl);
|
||||
}}
|
||||
keyPlaceholder="Label Key"
|
||||
valuePlaceholder="Label Value"
|
||||
tooltip="Labels to be used in nodeSelector assignation. Invalid key-pairs will be ignored"
|
||||
withBorder
|
||||
/>
|
||||
<span className={classes.error}>{validationErrors["labels"]}</span>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapState = (state: AppState) => ({
|
||||
podAffinity: state.tenants.createTenant.fields.affinity.podAffinity,
|
||||
affinityLabels: state.tenants.createTenant.fields.affinity.affinityLabels,
|
||||
});
|
||||
|
||||
const connector = connect(mapState, {
|
||||
setModalErrorSnackMessage,
|
||||
updateAddField,
|
||||
isPageValid,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(Affinity));
|
||||
@@ -10,7 +10,8 @@ import { Button, LinearProgress } from "@material-ui/core";
|
||||
import api from "../../../../common/api";
|
||||
import { IAddPoolRequest, ITenant } from "../ListTenants/types";
|
||||
import { IAffinityModel } from "../../../../common/types";
|
||||
import { getHardcodedAffinity } from "./utils";
|
||||
import { getDefaultAffinity } from "./utils";
|
||||
|
||||
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
|
||||
import { IQuotaElement, IQuotas, Opts } from "../ListTenants/utils";
|
||||
|
||||
@@ -121,7 +122,7 @@ const AddPoolModal = ({
|
||||
|
||||
const poolName = generatePoolName(tenant.pools);
|
||||
|
||||
const hardCodedAffinity: IAffinityModel = getHardcodedAffinity(
|
||||
const defaultAffinity: IAffinityModel = getDefaultAffinity(
|
||||
tenant.name,
|
||||
poolName
|
||||
);
|
||||
@@ -135,7 +136,7 @@ const AddPoolModal = ({
|
||||
storage_class_name: selectedStorageClass,
|
||||
labels: null,
|
||||
},
|
||||
affinity: hardCodedAffinity,
|
||||
affinity: defaultAffinity,
|
||||
};
|
||||
|
||||
api
|
||||
|
||||
@@ -14,9 +14,10 @@
|
||||
// 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 { IAffinityModel } from "../../../../common/types";
|
||||
import { ILabelKeyPair } from "../types";
|
||||
|
||||
export const getHardcodedAffinity = (tenantName: string, poolName: string) => {
|
||||
const hardCodedAffinity: IAffinityModel = {
|
||||
export const getDefaultAffinity = (tenantName: string, poolName: string) => {
|
||||
const defaultAffinity: IAffinityModel = {
|
||||
podAntiAffinity: {
|
||||
requiredDuringSchedulingIgnoredDuringExecution: [
|
||||
{
|
||||
@@ -39,5 +40,35 @@ export const getHardcodedAffinity = (tenantName: string, poolName: string) => {
|
||||
],
|
||||
},
|
||||
};
|
||||
return hardCodedAffinity;
|
||||
return defaultAffinity;
|
||||
};
|
||||
|
||||
export const getNodeSelector = (labels: string) => {
|
||||
// Labels in the form of key1=value1&key2=value2&key3=value3...
|
||||
const splittedLabels = labels.split("&");
|
||||
let labelItems: any = {};
|
||||
|
||||
splittedLabels.forEach((label: string) => {
|
||||
const splitKeyValue = label.split("=");
|
||||
if (splitKeyValue.length === 2) {
|
||||
labelItems = {
|
||||
...labelItems,
|
||||
[`${splitKeyValue[0]}`]: splitKeyValue[1],
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const nodeSelector: IAffinityModel = {
|
||||
podAffinity: {
|
||||
requiredDuringSchedulingIgnoredDuringExecution: [
|
||||
{
|
||||
labelSelector: {
|
||||
matchLabels: { ...labelItems },
|
||||
},
|
||||
topologyKey: "kubernetes.io/hostname",
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
return nodeSelector;
|
||||
};
|
||||
|
||||
@@ -154,6 +154,10 @@ const initialState: ITenantState = {
|
||||
},
|
||||
limitSize: {},
|
||||
},
|
||||
affinity: {
|
||||
affinityLabels: "",
|
||||
podAffinity: "default",
|
||||
},
|
||||
},
|
||||
certificates: {
|
||||
minioCertificates: [
|
||||
@@ -541,6 +545,10 @@ export function tenantsReducer(
|
||||
},
|
||||
limitSize: {},
|
||||
},
|
||||
affinity: {
|
||||
affinityLabels: "",
|
||||
podAffinity: "default",
|
||||
},
|
||||
},
|
||||
certificates: {
|
||||
minioCertificates: [
|
||||
|
||||
@@ -80,6 +80,7 @@ export interface IFieldStore {
|
||||
security: ISecurityFields;
|
||||
encryption: IEncryptionFields;
|
||||
tenantSize: ITenantSizeFields;
|
||||
affinity: ITenantAffinity;
|
||||
}
|
||||
|
||||
export interface INameTenantFields {
|
||||
@@ -177,10 +178,20 @@ export interface ITenantSizeFields {
|
||||
limitSize: any;
|
||||
}
|
||||
|
||||
export interface ITenantAffinity {
|
||||
podAffinity: "default" | "nodeSelector" | "none";
|
||||
affinityLabels: string;
|
||||
}
|
||||
|
||||
export interface ITenantState {
|
||||
createTenant: ICreateTenant;
|
||||
}
|
||||
|
||||
export interface ILabelKeyPair {
|
||||
labelKey: string;
|
||||
labelValue: string;
|
||||
}
|
||||
|
||||
interface SetTenantWizardPage {
|
||||
type: typeof ADD_TENANT_SET_CURRENT_PAGE;
|
||||
page: number;
|
||||
|
||||
Reference in New Issue
Block a user