Logging resources selector (#1402)

Added CPU and memory request selector to Log and Log DB
This commit is contained in:
jinapurapu
2022-01-31 21:17:21 -08:00
committed by GitHub
parent 27d1627c8f
commit 5258ac3d1a
7 changed files with 318 additions and 13 deletions

View File

@@ -66,6 +66,18 @@ type TenantLogs struct {
// labels
Labels []*Label `json:"labels"`
// log CPU request
LogCPURequest string `json:"logCPURequest,omitempty"`
// log d b CPU request
LogDBCPURequest string `json:"logDBCPURequest,omitempty"`
// log d b mem request
LogDBMemRequest string `json:"logDBMemRequest,omitempty"`
// log mem request
LogMemRequest string `json:"logMemRequest,omitempty"`
// node selector
NodeSelector []*NodeSelector `json:"nodeSelector"`

View File

@@ -3368,6 +3368,18 @@ func init() {
"$ref": "#/definitions/label"
}
},
"logCPURequest": {
"type": "string"
},
"logDBCPURequest": {
"type": "string"
},
"logDBMemRequest": {
"type": "string"
},
"logMemRequest": {
"type": "string"
},
"nodeSelector": {
"type": "array",
"items": {
@@ -7619,6 +7631,18 @@ func init() {
"$ref": "#/definitions/label"
}
},
"logCPURequest": {
"type": "string"
},
"logDBCPURequest": {
"type": "string"
},
"logDBMemRequest": {
"type": "string"
},
"logMemRequest": {
"type": "string"
},
"nodeSelector": {
"type": "array",
"items": {

View File

@@ -28,6 +28,7 @@ import (
"net"
"net/http"
"os"
"reflect"
"sort"
"strconv"
"strings"
@@ -237,6 +238,7 @@ func registerTenantHandlers(api *operations.OperatorAPI) {
//Get tenant monitoring info
api.OperatorAPIGetTenantMonitoringHandler = operator_api.GetTenantMonitoringHandlerFunc(func(params operator_api.GetTenantMonitoringParams, session *models.Principal) middleware.Responder {
payload, err := getTenantMonitoringResponse(session, params)
if err != nil {
return operator_api.NewGetTenantMonitoringDefault(int(err.Code)).WithPayload(err)
@@ -1789,14 +1791,6 @@ func getTenantLogsResponse(session *models.Principal, params operator_api.GetTen
minTenant.Spec.Log.Audit = &miniov2.AuditConfig{DiskCapacityGB: swag.Int(0)}
}
/*if minTenant.Spec.Log.Image == "" {
minTenant.Spec.Log.Image = miniov2.DefaultLogSearchAPIImage
}
if minTenant.Spec.Log.Db.Image == "" {
minTenant.Spec.Log.Db.Image = miniov2.LogPgImage
}*/
retval := &models.TenantLogs{
Image: minTenant.Spec.Log.Image,
DiskCapacityGB: fmt.Sprintf("%d", *minTenant.Spec.Log.Audit.DiskCapacityGB),
@@ -1811,11 +1805,33 @@ func getTenantLogsResponse(session *models.Principal, params operator_api.GetTen
DbServiceAccountName: minTenant.Spec.Log.Db.ServiceAccountName,
Disabled: false,
}
var requestedCPU string
var requestedMem string
var requestedDBCPU string
var requestedDBMem string
if minTenant.Spec.Log.Resources.Requests != nil {
requestedCPUQ := minTenant.Spec.Log.Resources.Requests["cpu"]
requestedCPU = strconv.FormatInt(requestedCPUQ.Value(), 10)
requestedMemQ := minTenant.Spec.Log.Resources.Requests["memory"]
requestedMem = strconv.FormatInt(requestedMemQ.Value(), 10)
requestedDBCPUQ := minTenant.Spec.Log.Db.Resources.Requests["cpu"]
requestedDBCPU = strconv.FormatInt(requestedDBCPUQ.Value(), 10)
requestedDBMemQ := minTenant.Spec.Log.Db.Resources.Requests["memory"]
requestedDBMem = strconv.FormatInt(requestedDBMemQ.Value(), 10)
retval.LogCPURequest = requestedCPU
retval.LogMemRequest = requestedMem
retval.LogDBCPURequest = requestedDBCPU
retval.LogDBMemRequest = requestedDBMem
}
return retval, nil
}
// setTenantLogsResponse returns the logs of a tenant
func setTenantLogsResponse(session *models.Principal, params operator_api.SetTenantLogsParams) (bool, *models.Error) {
// 30 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
@@ -1833,6 +1849,7 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
if err != nil {
return false, prepareError(err, errorUnableToGetTenantUsage)
}
var labels = make(map[string]string)
for i := 0; i < len(params.Data.Labels); i++ {
if params.Data.Labels[i] != nil {
@@ -1854,6 +1871,26 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
}
}
minTenant.Spec.Log.NodeSelector = nodeSelector
logResourceRequest := make(corev1.ResourceList)
if reflect.TypeOf(params.Data.LogCPURequest).Kind() == reflect.String && params.Data.LogCPURequest != "0Gi" && params.Data.LogCPURequest != "" {
cpuQuantity, err := resource.ParseQuantity(params.Data.LogCPURequest)
if err != nil {
return false, prepareError(err)
}
logResourceRequest["cpu"] = cpuQuantity
minTenant.Spec.Log.Resources.Requests = logResourceRequest
}
if reflect.TypeOf(params.Data.LogMemRequest).Kind() == reflect.String {
memQuantity, err := resource.ParseQuantity(params.Data.LogMemRequest)
if err != nil {
return false, prepareError(err)
}
logResourceRequest["memory"] = memQuantity
minTenant.Spec.Log.Resources.Requests = logResourceRequest
}
modified := false
if minTenant.Spec.Log.Db != nil {
modified = true
@@ -1879,6 +1916,24 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
}
modified = true
}
logDBResourceRequest := make(corev1.ResourceList)
if reflect.TypeOf(params.Data.LogDBCPURequest).Kind() == reflect.String && params.Data.LogDBCPURequest != "0Gi" && params.Data.LogDBCPURequest != "" {
dbCPUQuantity, err := resource.ParseQuantity(params.Data.LogDBCPURequest)
if err != nil {
return false, prepareError(err)
}
logDBResourceRequest["cpu"] = dbCPUQuantity
minTenant.Spec.Log.Db.Resources.Requests = logDBResourceRequest
}
if reflect.TypeOf(params.Data.LogDBMemRequest).Kind() == reflect.String {
dbMemQuantity, err := resource.ParseQuantity(params.Data.LogDBMemRequest)
if err != nil {
return false, prepareError(err)
}
logDBResourceRequest["memory"] = dbMemQuantity
minTenant.Spec.Log.Db.Resources.Requests = logDBResourceRequest
}
minTenant.Spec.Log.Image = params.Data.Image
diskCapacityGB, err := strconv.Atoi(params.Data.DiskCapacityGB)
if err == nil {
@@ -1922,6 +1977,9 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
NodeSelector: dbNodeSelector,
Image: params.Data.DbImage,
ServiceAccountName: params.Data.DbServiceAccountName,
Resources: corev1.ResourceRequirements{
Requests: minTenant.Spec.Log.Db.Resources.Requests,
},
}
} else {
minTenant.Spec.Log.Db.Labels = dbLabels
@@ -1931,6 +1989,7 @@ func setTenantLogsResponse(session *models.Principal, params operator_api.SetTen
minTenant.Spec.Log.Db.ServiceAccountName = params.Data.DbServiceAccountName
}
}
_, err = opClient.TenantUpdate(ctx, minTenant, metav1.UpdateOptions{})
if err != nil {
return false, prepareError(err)

View File

@@ -177,6 +177,10 @@ export interface ITenantLogsStruct {
dbNodeSelector: IKeyValue[];
dbServiceAccountName: string;
disabled: boolean;
logCPURequest: string;
logMemRequest: string;
logDBCPURequest: string;
logDBMemRequest: string;
}
export interface ValueUnit {

View File

@@ -1,3 +1,19 @@
// 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 React, { useEffect, useState } from "react";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import createStyles from "@mui/styles/createStyles";
@@ -38,6 +54,10 @@ interface IEditTenantLogsProps {
dbAnnotations: IKeyValue[];
dbNodeSelector: IKeyValue[];
dbServiceAccountName: string;
cpuRequest: string;
memRequest: string;
dbCPURequest:string;
dbMemRequest:string;
}
const styles = (theme: Theme) =>
@@ -102,6 +122,10 @@ const EditTenantLogsModal = ({
dbNodeSelector,
dbImage,
dbServiceAccountName,
cpuRequest,
memRequest,
dbCPURequest,
dbMemRequest
}: IEditTenantLogsProps) => {
const [validationErrors, setValidationErrors] = useState<any>({});
const [newLabels, setNewLabels] = useState<IKeyValue[]>(
@@ -137,6 +161,14 @@ const EditTenantLogsModal = ({
const [dbLabelsError, setDbLabelsError] = useState<any>({});
const [dbAnnotationsError, setDbAnnotationsError] = useState<any>({});
const [dbNodeSelectorError, setDbNodeSelectorError] = useState<any>({});
const [newCPURequest, setNewCPURequest] = useState<string>(cpuRequest);
const [newMemRequest, setNewMemRequest] = useState<string>( memRequest ?
Math.floor(parseInt(memRequest, 10) / 1000000000).toString() : "0"
);
const [newDBCPURequest, setNewDBCPURequest] = useState<string>(dbCPURequest);
const [newDBMemRequest, setNewDBMemRequest] = useState<string>(dbMemRequest ?
Math.floor(parseInt(dbMemRequest, 10) / 1000000000).toString() : "0"
);
const trim = (x: IKeyValue[]): IKeyValue[] => {
let retval: IKeyValue[] = [];
@@ -192,6 +224,34 @@ const EditTenantLogsModal = ({
pattern: /^[a-zA-Z0-9-.]{1,253}$/,
customPatternMessage: "Invalid service account name",
});
tenantLogValidation.push({
fieldKey: `cpuRequest`,
required: true,
value: newCPURequest as any as string,
pattern: /^[0-9]*$/,
customPatternMessage: "Please enter an integer value for number of CPUs requested",
});
tenantLogValidation.push({
fieldKey: `memRequest`,
required: true,
value: newMemRequest as any as string,
pattern: /^[0-9]*$/,
customPatternMessage: "Please enter an integer value (Gi) for memory requested",
});
tenantLogValidation.push({
fieldKey: `dbCPURequest`,
required: true,
value: newDBCPURequest as any as string,
pattern: /^[0-9]*$/,
customPatternMessage: "Please enter an integer value for number of DB CPUs requested",
});
tenantLogValidation.push({
fieldKey: `dbMemRequest`,
required: true,
value: newDBMemRequest as any as string,
pattern: /^[0-9]*$/,
customPatternMessage: "Please enter an integer value (Gi) for DB memory requested",
});
const commonVal = commonFormValidation(tenantLogValidation);
setValidationErrors(commonVal);
@@ -201,6 +261,10 @@ const EditTenantLogsModal = ({
newDiskCapacityGB,
newServiceAccountName,
newDbServiceAccountName,
newCPURequest,
newMemRequest,
newDBCPURequest,
newDBMemRequest,
setValidationErrors,
]);
@@ -253,6 +317,10 @@ const EditTenantLogsModal = ({
dbNodeSelector: trim(newDbNodeSelector),
dbImage: newDbImage,
dbServiceAccountName: newDbServiceAccountName,
logCPURequest: newCPURequest,
logMemRequest: newMemRequest + "Gi",
logDBCPURequest: newDBCPURequest,
logDBMemRequest: newDBMemRequest+ "Gi",
}
)
.then(() => {
@@ -312,6 +380,38 @@ const EditTenantLogsModal = ({
error={validationErrors[`serviceAccountName`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id={`cpuRequest`}
label={"CPU Request"}
placeholder={"CPU Request"}
name={`cpuRequest`}
value={newCPURequest as any as string}
onChange={(e) => {
setNewCPURequest(e.target.value as any as string);
cleanValidation(`cpuRequest`);
}}
key={`cpuRequest`}
error={validationErrors[`cpuRequest`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id={`memRequest`}
label={"Memory request"}
placeholder={"Memory request"}
name={`memRequest`}
value={newMemRequest}
onChange={(e) => {
setNewMemRequest(e.target.value as any as string);
cleanValidation(`memRequest`);
}}
key={`memRequest`}
error={validationErrors[`memRequest`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<span className={classes.inputLabel}>Labels</span>
<KeyPairEdit
@@ -375,6 +475,36 @@ const EditTenantLogsModal = ({
error={validationErrors[`dbServiceAccountName`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id={`dbCpuRequest`}
label={"DB CPU Request"}
placeholder={"DB CPU Request"}
name={`dbCpuRequest`}
value={newDBCPURequest as any as string}
onChange={(e) => {
setNewDBCPURequest(e.target.value as any as string);
cleanValidation(`dbCpuRequest`);
}}
key={`dbCpuRequest`}
error={validationErrors[`dbCpuRequest`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
id={`dbMemRequest`}
label={"DB Memory request"}
placeholder={"DB Memory request"}
name={`dbMemRequest`}
value={newDBMemRequest}
onChange={(e) => {
setNewDBMemRequest(e.target.value as any as string);
cleanValidation(`dbMemRequest`);
}}
key={`dbMemRequest`}
error={validationErrors[`dbMemRequest`] || ""}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<span className={classes.inputLabel}>Labels</span>
<KeyPairEdit
@@ -422,4 +552,4 @@ const EditTenantLogsModal = ({
);
};
export default withStyles(styles)(EditTenantLogsModal);
export default withStyles(styles)(EditTenantLogsModal);

View File

@@ -40,6 +40,7 @@ import { ITenantLogsStruct } from "../ListTenants/types";
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
import { niceBytes } from "../../../../common/utils";
interface ITenantLogs {
classes: any;
@@ -199,6 +200,10 @@ const TenantLogging = ({
dbAnnotations={logInfo.dbAnnotations}
dbNodeSelector={logInfo.dbNodeSelector}
dbServiceAccountName={logInfo.dbServiceAccountName}
cpuRequest={logInfo.logCPURequest}
memRequest={logInfo.logMemRequest}
dbCPURequest={logInfo.logDBCPURequest}
dbMemRequest={logInfo.logDBMemRequest}
/>
)}
<h1 className={classes.sectionTitle}>Logging</h1>
@@ -249,25 +254,49 @@ const TenantLogging = ({
</tr>
) : (
<Fragment>
{logInfo?.logCPURequest != null && (
<tr>
<td className={classes.titleCol}>CPU Request:</td>
<td>{logInfo?.logCPURequest}</td>
</tr>
)}
{logInfo?.logMemRequest != null && (
<tr>
<td className={classes.titleCol}>Memory Request:</td>
<td>
{niceBytes(
logInfo?.logMemRequest,
true
)}
</td>
</tr>
)}
{logInfo?.image != null && (
<tr>
<td className={classes.titleCol}>Image:</td>
<td>{logInfo?.image}</td>
</tr>
)}
{logInfo?.diskCapacityGB != null && (
<tr>
<td className={classes.titleCol}>
Disk Capacity (GB):
</td>
<td>{logInfo?.diskCapacityGB}</td>
</tr>
)}
{logInfo?.serviceAccountName != null && (
<tr>
<td className={classes.titleCol}>Service Account:</td>
<td>{logInfo?.serviceAccountName}</td>
</tr>
)}
{logInfo?.labels != null && logInfo.labels.length > 0 && (<Fragment>
<tr>
<td>
<h4>Labels</h4>
</td>
</tr>
</tr>
<tr>
<td>
<KeyPairView
@@ -280,6 +309,9 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
{logInfo?.annotations != null && logInfo.annotations.length > 0 && (<Fragment>
<tr>
<td>
<h4>Annotations</h4>
@@ -297,6 +329,9 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
{logInfo?.nodeSelector != null && logInfo.nodeSelector.length > 0 &&(<Fragment>
<tr>
<td>
<h4>Node Selector</h4>
@@ -314,6 +349,8 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
</Fragment>
)}
</tbody>
@@ -331,19 +368,41 @@ const TenantLogging = ({
</tr>
) : (
<Fragment>
{logInfo?.logDBCPURequest != null && (
<tr>
<td className={classes.titleCol}>DB CPU Request:</td>
<td>{logInfo?.logDBCPURequest}</td>
</tr>
)}
{logInfo?.logDBMemRequest != null && (
<tr>
<td className={classes.titleCol}>DB Memory Request:</td>
<td>
{niceBytes(
logInfo?.logDBMemRequest,
true
)}
</td>
</tr>
)}
{logInfo?.dbImage != null && (
<tr>
<td className={classes.titleCol}>Postgres Image:</td>
<td>{logInfo?.dbImage}</td>
</tr>
)}
{logInfo?.dbServiceAccountName != null && (
<tr>
<td className={classes.titleCol}>Service Account:</td>
<td>{logInfo?.dbServiceAccountName}</td>
</tr>
<tr>
</tr>
)}
{logInfo?.dbLabels != null && logInfo.dbLabels.length > 0 &&(<Fragment><tr>
<td>
<h4>Labels</h4>
</td>
</tr>
<tr>
<td>
<KeyPairView
@@ -356,6 +415,9 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
{logInfo?.annotations != null && logInfo.dbAnnotations.length > 0 &&(<Fragment>
<tr>
<td>
<h4>Annotations</h4>
@@ -374,9 +436,12 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
{logInfo?.nodeSelector != null && logInfo.dbNodeSelector.length > 0 &&(<Fragment>
<tr>
<td>
<h4>Node Selector</h4>
<h4>Node Selector </h4>
</td>
</tr>
<tr>
@@ -392,6 +457,8 @@ const TenantLogging = ({
/>
</td>
</tr>
</Fragment>
)}
</Fragment>
)}
</tbody>

View File

@@ -2521,6 +2521,15 @@ definitions:
type: string
disabled:
type: boolean
logCPURequest:
type: string
logMemRequest:
type: string
logDBCPURequest:
type: string
logDBMemRequest:
type: string
listPVCsResponse:
type: object