Fix spacing on Add tenant forms (#1895)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-04-22 21:59:18 -07:00
committed by GitHub
parent 66df609d4a
commit 8a96d8d8a5
9 changed files with 1413 additions and 1350 deletions

View File

@@ -0,0 +1,29 @@
// 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 from "react";
type Props = {};
const SectionH1: React.FC<Props> = ({ children }) => {
return (
<h1 style={{ margin: 0, marginBottom: ".8rem", fontSize: "1.3rem" }}>
{children}
</h1>
);
};
export default SectionH1;

View File

@@ -14,7 +14,7 @@
// 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, { useCallback, useEffect, useState } from "react";
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -37,6 +37,7 @@ import InputBoxWrapper from "../../../Common/FormComponents/InputBoxWrapper/Inpu
import SelectWrapper from "../../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { ISecurityContext } from "../../types";
import InputUnitMenu from "../../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import SectionH1 from "../../../Common/SectionH1";
interface IConfigureProps {
updateAddField: typeof updateAddField;
@@ -250,274 +251,287 @@ const ConfigLogSearch = ({
return (
<Paper className={classes.paperWrapper}>
<div className={classes.headerElement}>
<h3 className={classes.h3Section}>Audit Log</h3>
<span className={classes.descriptionText}>
Audit log deploys a small PostgreSQL database and stores access logs
of all calls into the tenant.
</span>
</div>
<Grid item xs={12} className={classes.configSectionItem}>
<FormSwitchWrapper
value="logSearchConfig"
id="log-search-enabled"
name="log_search_enabled"
checked={logSearchEnabled}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchEnabled", checked);
}}
label={"Enabled"}
/>
</Grid>
{logSearchEnabled && (
<Grid xs={12} className={classes.logSearchEnabledFields}>
<Grid item xs={12}>
<SelectWrapper
id="log_search_storage_class"
name="log_search_storage_class"
onChange={(e: SelectChangeEvent<string>) => {
updateField(
"logSearchSelectedStorageClass",
e.target.value as string
);
}}
label="Log Search Storage Class"
value={logSearchSelectedStorageClass}
options={configureSTClasses}
disabled={configureSTClasses.length < 1}
/>
</Grid>
<Grid item xs={12}>
<div className={classes.multiContainer}>
<InputBoxWrapper
type="number"
id="log_search_volume_size"
name="log_search_volume_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchVolumeSize", e.target.value);
cleanValidation("log_search_volume_size");
}}
label="Storage Size"
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={() => {}}
unitSelected={"Gi"}
unitsList={[{ label: "Gi", value: "Gi" }]}
disabled={true}
/>
}
value={logSearchVolumeSize}
required
error={validationErrors["log_search_volume_size"] || ""}
min="0"
/>
</div>
</Grid>
<fieldset
className={`${classes.fieldGroup} ${classes.fieldSpaceTop}`}
>
<legend className={classes.descriptionText}>
SecurityContext for LogSearch
</legend>
<Grid item xs={12}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_runAsUser"
name="logSearch_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("logSearch_securityContext_runAsUser");
}}
label="Run As User"
value={logSearchSecurityContext.runAsUser}
required
error={
validationErrors["logSearch_securityContext_runAsUser"] ||
""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_runAsGroup"
name="logSearch_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation("logSearch_securityContext_runAsGroup");
}}
label="Run As Group"
value={logSearchSecurityContext.runAsGroup}
required
error={
validationErrors[
"logSearch_securityContext_runAsGroup"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_fsGroup"
name="logSearch_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("logSearch_securityContext_fsGroup");
}}
label="FsGroup"
value={logSearchSecurityContext.fsGroup}
required
error={
validationErrors["logSearch_securityContext_fsGroup"] ||
""
}
min="0"
/>
</div>
</div>
</Grid>
<br />
<Grid item xs={12}>
<div className={classes.multiContainer}>
<FormSwitchWrapper
value="logSearchSecurityContextRunAsNonRoot"
id="logSearch_securityContext_runAsNonRoot"
name="logSearch_securityContext_runAsNonRoot"
checked={logSearchSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsNonRoot: checked,
});
}}
label={"Do not run as Root"}
/>
</div>
</Grid>
</fieldset>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
SecurityContext for PostgreSQL
</legend>
<Grid item xs={12}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_runAsUser"
name="postgres_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("postgres_securityContext_runAsUser");
}}
label="Run As User"
value={logSearchPostgresSecurityContext.runAsUser}
required
error={
validationErrors["postgres_securityContext_runAsUser"] ||
""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_runAsGroup"
name="postgres_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation("postgres_securityContext_runAsGroup");
}}
label="Run As Group"
value={logSearchPostgresSecurityContext.runAsGroup}
required
error={
validationErrors["postgres_securityContext_runAsGroup"] ||
""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_fsGroup"
name="postgres_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("postgres_securityContext_fsGroup");
}}
label="FsGroup"
value={logSearchPostgresSecurityContext.fsGroup}
required
error={
validationErrors["postgres_securityContext_fsGroup"] || ""
}
min="0"
/>
</div>
</div>
</Grid>
<br />
<Grid item xs={12}>
<div className={classes.multiContainer}>
<FormSwitchWrapper
value="postgresSecurityContextRunAsNonRoot"
id="postgres_securityContext_runAsNonRoot"
name="postgres_securityContext_runAsNonRoot"
checked={logSearchPostgresSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsNonRoot: checked,
});
}}
label={"Do not run as Root"}
/>
</div>
</Grid>
</fieldset>
<Grid container alignItems={"center"}>
<Grid item xs>
<SectionH1>Audit Log</SectionH1>
</Grid>
)}
<Grid item xs={4}>
<FormSwitchWrapper
value="enableLogging"
id="enableLogging"
name="enableLogging"
checked={logSearchEnabled}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchEnabled", checked);
}}
indicatorLabels={["Enabled", "Disabled"]}
/>
</Grid>
</Grid>
<Grid container spacing={1}>
<Grid item xs={12}>
<span className={classes.descriptionText}>
Deploys a small PostgreSQL database and stores access logs of all
calls into the tenant.
</span>
</Grid>
<Grid xs={12}>
<hr className={classes.hrClass} />
</Grid>
{logSearchEnabled && (
<Fragment>
<Grid item xs={12}>
<SelectWrapper
id="log_search_storage_class"
name="log_search_storage_class"
onChange={(e: SelectChangeEvent<string>) => {
updateField(
"logSearchSelectedStorageClass",
e.target.value as string
);
}}
label="Log Search Storage Class"
value={logSearchSelectedStorageClass}
options={configureSTClasses}
disabled={configureSTClasses.length < 1}
/>
</Grid>
<Grid item xs={12}>
<div className={classes.multiContainer}>
<InputBoxWrapper
type="number"
id="log_search_volume_size"
name="log_search_volume_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchVolumeSize", e.target.value);
cleanValidation("log_search_volume_size");
}}
label="Storage Size"
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={() => {}}
unitSelected={"Gi"}
unitsList={[{ label: "Gi", value: "Gi" }]}
disabled={true}
/>
}
value={logSearchVolumeSize}
required
error={validationErrors["log_search_volume_size"] || ""}
min="0"
/>
</div>
</Grid>
<fieldset
className={`${classes.fieldGroup} ${classes.fieldSpaceTop}`}
>
<legend className={classes.descriptionText}>
SecurityContext for LogSearch
</legend>
<Grid item xs={12}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_runAsUser"
name="logSearch_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("logSearch_securityContext_runAsUser");
}}
label="Run As User"
value={logSearchSecurityContext.runAsUser}
required
error={
validationErrors[
"logSearch_securityContext_runAsUser"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_runAsGroup"
name="logSearch_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation("logSearch_securityContext_runAsGroup");
}}
label="Run As Group"
value={logSearchSecurityContext.runAsGroup}
required
error={
validationErrors[
"logSearch_securityContext_runAsGroup"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="logSearch_securityContext_fsGroup"
name="logSearch_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("logSearch_securityContext_fsGroup");
}}
label="FsGroup"
value={logSearchSecurityContext.fsGroup}
required
error={
validationErrors["logSearch_securityContext_fsGroup"] ||
""
}
min="0"
/>
</div>
</div>
</Grid>
<br />
<Grid item xs={12}>
<div className={classes.multiContainer}>
<FormSwitchWrapper
value="logSearchSecurityContextRunAsNonRoot"
id="logSearch_securityContext_runAsNonRoot"
name="logSearch_securityContext_runAsNonRoot"
checked={logSearchSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchSecurityContext", {
...logSearchSecurityContext,
runAsNonRoot: checked,
});
}}
label={"Do not run as Root"}
/>
</div>
</Grid>
</fieldset>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
SecurityContext for PostgreSQL
</legend>
<Grid item xs={12}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_runAsUser"
name="postgres_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("postgres_securityContext_runAsUser");
}}
label="Run As User"
value={logSearchPostgresSecurityContext.runAsUser}
required
error={
validationErrors[
"postgres_securityContext_runAsUser"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_runAsGroup"
name="postgres_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation("postgres_securityContext_runAsGroup");
}}
label="Run As Group"
value={logSearchPostgresSecurityContext.runAsGroup}
required
error={
validationErrors[
"postgres_securityContext_runAsGroup"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="postgres_securityContext_fsGroup"
name="postgres_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("postgres_securityContext_fsGroup");
}}
label="FsGroup"
value={logSearchPostgresSecurityContext.fsGroup}
required
error={
validationErrors["postgres_securityContext_fsGroup"] ||
""
}
min="0"
/>
</div>
</div>
</Grid>
<br />
<Grid item xs={12}>
<div className={classes.multiContainer}>
<FormSwitchWrapper
value="postgresSecurityContextRunAsNonRoot"
id="postgres_securityContext_runAsNonRoot"
name="postgres_securityContext_runAsNonRoot"
checked={logSearchPostgresSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("logSearchPostgresSecurityContext", {
...logSearchPostgresSecurityContext,
runAsNonRoot: checked,
});
}}
label={"Do not run as Root"}
/>
</div>
</Grid>
</fieldset>
</Fragment>
)}
</Grid>
</Paper>
);
};

View File

@@ -14,7 +14,7 @@
// 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, { useCallback, useEffect, useState } from "react";
import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -37,6 +37,7 @@ import InputBoxWrapper from "../../../Common/FormComponents/InputBoxWrapper/Inpu
import SelectWrapper from "../../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { ISecurityContext } from "../../types";
import InputUnitMenu from "../../../Common/FormComponents/InputUnitMenu/InputUnitMenu";
import SectionH1 from "../../../Common/SectionH1";
interface IConfigureProps {
updateAddField: typeof updateAddField;
@@ -219,176 +220,189 @@ const ConfigPrometheus = ({
return (
<Paper className={classes.paperWrapper}>
<div className={classes.headerElement}>
<h3 className={classes.h3Section}>Monitoring</h3>
<Grid container alignItems={"center"}>
<Grid item xs>
<SectionH1>Monitoring</SectionH1>
</Grid>
<Grid item xs={4}>
<FormSwitchWrapper
indicatorLabels={["Enabled", "Disabled"]}
checked={prometheusEnabled}
value={"monitoring_status"}
id="monitoring-status"
name="monitoring-status"
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("prometheusEnabled", checked);
}}
description=""
/>
</Grid>
</Grid>
<Grid item xs={12}>
<span className={classes.descriptionText}>
A small Prometheus will be deployed to keep metrics about the tenant.
</span>
</div>
<Grid item xs={12} className={classes.configSectionItem}>
<FormSwitchWrapper
value="prometheusConfig"
id="prometheus_configuration"
name="prometheus_configuration"
checked={prometheusEnabled}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("prometheusEnabled", checked);
}}
label={"Enabled"}
/>
</Grid>
{prometheusEnabled && (
<Grid xs={12} className={classes.prometheusEnabledFields}>
<Grid item xs={12}>
<SelectWrapper
id="prometheus_storage_class"
name="prometheus_storage_class"
onChange={(e: SelectChangeEvent<string>) => {
updateField(
"prometheusSelectedStorageClass",
e.target.value as string
);
}}
label="Prometheus Storage Class"
value={prometheusSelectedStorageClass}
options={configureSTClasses}
disabled={configureSTClasses.length < 1}
/>
</Grid>
<Grid item xs={12}>
<div className={classes.multiContainer}>
<InputBoxWrapper
type="number"
id="prometheus_volume_size"
name="prometheus_volume_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusVolumeSize", e.target.value);
cleanValidation("prometheus_volume_size");
<Grid xs={12}>
<hr className={classes.hrClass} />
</Grid>
<Grid container spacing={1}>
{prometheusEnabled && (
<Fragment>
<Grid item xs={12}>
<SelectWrapper
id="prometheus_storage_class"
name="prometheus_storage_class"
onChange={(e: SelectChangeEvent<string>) => {
updateField(
"prometheusSelectedStorageClass",
e.target.value as string
);
}}
label="Storage Size"
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={() => {}}
unitSelected={"Gi"}
unitsList={[{ label: "Gi", value: "Gi" }]}
disabled={true}
/>
}
value={prometheusVolumeSize}
required
error={validationErrors["prometheus_volume_size"] || ""}
min="0"
label="Storage Class"
value={prometheusSelectedStorageClass}
options={configureSTClasses}
disabled={configureSTClasses.length < 1}
/>
</div>
</Grid>
<fieldset
className={`${classes.fieldGroup} ${classes.fieldSpaceTop}`}
>
<legend className={classes.descriptionText}>
SecurityContext for Prometheus
</legend>
<Grid item xs={12} className={classes.configSectionItem}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_runAsUser"
name="prometheus_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("prometheus_securityContext_runAsUser");
}}
label="Run As User"
value={prometheusSecurityContext.runAsUser}
required
error={
validationErrors[
"prometheus_securityContext_runAsUser"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_runAsGroup"
name="prometheus_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation("prometheus_securityContext_runAsGroup");
}}
label="Run As Group"
value={prometheusSecurityContext.runAsGroup}
required
error={
validationErrors[
"prometheus_securityContext_runAsGroup"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_fsGroup"
name="prometheus_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("prometheus_securityContext_fsGroup");
}}
label="FsGroup"
value={prometheusSecurityContext.fsGroup}
required
error={
validationErrors["prometheus_securityContext_fsGroup"] ||
""
}
min="0"
/>
</div>
</div>
</Grid>
<Grid item xs={12} className={classes.configSectionItem}>
<div
className={`${classes.multiContainer} ${classes.fieldSpaceTop}`}
>
<FormSwitchWrapper
value="prometheusSecurityContextRunAsNonRoot"
id="prometheus_securityContext_runAsNonRoot"
name="prometheus_securityContext_runAsNonRoot"
checked={prometheusSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsNonRoot: checked,
});
<Grid item xs={12}>
<div className={classes.multiContainer}>
<InputBoxWrapper
type="number"
id="prometheus_volume_size"
name="prometheus_volume_size"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusVolumeSize", e.target.value);
cleanValidation("prometheus_volume_size");
}}
label={"Do not run as Root"}
label="Storage Size"
overlayObject={
<InputUnitMenu
id={"size-unit"}
onUnitChange={() => {}}
unitSelected={"Gi"}
unitsList={[{ label: "Gi", value: "Gi" }]}
disabled={true}
/>
}
value={prometheusVolumeSize}
required
error={validationErrors["prometheus_volume_size"] || ""}
min="0"
/>
</div>
</Grid>
</fieldset>
</Grid>
)}
<fieldset
className={`${classes.fieldGroup} ${classes.fieldSpaceTop}`}
>
<legend className={classes.descriptionText}>
SecurityContext
</legend>
<Grid item xs={12} className={classes.configSectionItem}>
<div
className={`${classes.multiContainer} ${classes.responsiveSectionItem}`}
>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_runAsUser"
name="prometheus_securityContext_runAsUser"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsUser: e.target.value,
});
cleanValidation("prometheus_securityContext_runAsUser");
}}
label="Run As User"
value={prometheusSecurityContext.runAsUser}
required
error={
validationErrors[
"prometheus_securityContext_runAsUser"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_runAsGroup"
name="prometheus_securityContext_runAsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsGroup: e.target.value,
});
cleanValidation(
"prometheus_securityContext_runAsGroup"
);
}}
label="Run As Group"
value={prometheusSecurityContext.runAsGroup}
required
error={
validationErrors[
"prometheus_securityContext_runAsGroup"
] || ""
}
min="0"
/>
</div>
<div className={classes.configSectionItem}>
<InputBoxWrapper
type="number"
id="prometheus_securityContext_fsGroup"
name="prometheus_securityContext_fsGroup"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
fsGroup: e.target.value,
});
cleanValidation("prometheus_securityContext_fsGroup");
}}
label="FsGroup"
value={prometheusSecurityContext.fsGroup}
required
error={
validationErrors[
"prometheus_securityContext_fsGroup"
] || ""
}
min="0"
/>
</div>
</div>
</Grid>
<Grid item xs={12} className={classes.configSectionItem}>
<div
className={`${classes.multiContainer} ${classes.fieldSpaceTop}`}
>
<FormSwitchWrapper
value="prometheusSecurityContextRunAsNonRoot"
id="prometheus_securityContext_runAsNonRoot"
name="prometheus_securityContext_runAsNonRoot"
checked={prometheusSecurityContext.runAsNonRoot}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("prometheusSecurityContext", {
...prometheusSecurityContext,
runAsNonRoot: checked,
});
}}
label={"Do not run as Root"}
/>
</div>
</Grid>
</fieldset>
</Fragment>
)}
</Grid>
</Paper>
);
};

View File

@@ -19,7 +19,7 @@ import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Grid, IconButton, Paper, Typography } from "@mui/material";
import { Grid, IconButton, Paper } from "@mui/material";
import {
createTenantCommon,
modalBasic,
@@ -41,6 +41,7 @@ import FormSwitchWrapper from "../../../Common/FormComponents/FormSwitchWrapper/
import FileSelector from "../../../Common/FormComponents/FileSelector/FileSelector";
import AddIcon from "../../../../../icons/AddIcon";
import RemoveIcon from "../../../../../icons/RemoveIcon";
import SectionTitle from "../../../Common/SectionTitle";
interface ISecurityProps {
classes: any;
@@ -174,117 +175,158 @@ const Security = ({
<div className={classes.headerElement}>
<h3 className={classes.h3Section}>Security</h3>
</div>
<Grid item xs={12}>
<FormSwitchWrapper
value="enableTLS"
id="enableTLS"
name="enableTLS"
checked={enableTLS}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
<Grid container spacing={1}>
<Grid item xs={12}>
<FormSwitchWrapper
value="enableTLS"
id="enableTLS"
name="enableTLS"
checked={enableTLS}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("enableTLS", checked);
}}
label={"Enable TLS"}
/>
Enable TLS for the tenant, this is required for Encryption Configuration
updateField("enableTLS", checked);
}}
label={"TLS"}
description={
"Securing all the traffic using TLS. This is required for Encryption Configuration"
}
/>
</Grid>
{enableTLS && (
<Fragment>
<br />
<br />
<Typography variant="caption" display="block" gutterBottom>
AutoCert: MinIO Operator will generate all TLS certificates
automatically
</Typography>
<Typography variant="caption" display="block" gutterBottom>
Custom certificates: Allow user to provide your own certificates
</Typography>
<br />
</Fragment>
)}
</Grid>
{enableTLS && (
<Fragment>
<Grid item xs={12}>
<FormSwitchWrapper
value="enableAutoCert"
id="enableAutoCert"
name="enableAutoCert"
checked={enableAutoCert}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("enableAutoCert", checked);
}}
label={"Enable AutoCert"}
/>
<FormSwitchWrapper
value="enableCustomCerts"
id="enableCustomCerts"
name="enableCustomCerts"
checked={enableCustomCerts}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("enableCustomCerts", checked);
}}
label={"Custom Certificates"}
/>
</Grid>
{enableCustomCerts && (
<Fragment>
<Grid container>
<Grid item xs={12}>
<FormSwitchWrapper
value="enableAutoCert"
id="enableAutoCert"
name="enableAutoCert"
checked={enableAutoCert}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("enableAutoCert", checked);
}}
label={"AutoCert"}
description={
"The internode certificates will be generated and managed by MinIO Operator"
}
/>
</Grid>
<Grid item xs={12}>
<FormSwitchWrapper
value="enableCustomCerts"
id="enableCustomCerts"
name="enableCustomCerts"
checked={enableCustomCerts}
onChange={(e) => {
const targetD = e.target;
const checked = targetD.checked;
updateField("enableCustomCerts", checked);
}}
label={"Custom Certificates"}
description={"Certificates used to terminated TLS at MinIO"}
/>
</Grid>
{enableCustomCerts && (
<Fragment>
<Grid item xs={12} className={classes.minioCertsContainer}>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
MinIO Certificates
</legend>
{minioCertificates.map((keyPair: KeyPair) => (
<Grid
item
xs={12}
key={`minio-certs-${keyPair.id}`}
className={classes.minioCertificateRows}
>
<Grid item xs={10} className={classes.fileItem}>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToKeyPair(
keyPair.id,
"cert",
fileName,
encodedValue
);
}}
accept=".cer,.crt,.cert,.pem"
id="tlsCert"
name="tlsCert"
label="Cert"
value={keyPair.cert}
/>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToKeyPair(
keyPair.id,
"key",
fileName,
encodedValue
);
}}
accept=".key,.pem"
id="tlsKey"
name="tlsKey"
label="Key"
value={keyPair.key}
/>
</Grid>
<SectionTitle>MinIO Certificates</SectionTitle>
{minioCertificates.map((keyPair: KeyPair) => (
<Grid
item
xs={12}
key={`minio-certs-${keyPair.id}`}
className={classes.minioCertificateRows}
>
<Grid item xs={10} className={classes.fileItem}>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToKeyPair(
keyPair.id,
"cert",
fileName,
encodedValue
);
}}
accept=".cer,.crt,.cert,.pem"
id="tlsCert"
name="tlsCert"
label="Cert"
value={keyPair.cert}
/>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToKeyPair(
keyPair.id,
"key",
fileName,
encodedValue
);
}}
accept=".key,.pem"
id="tlsKey"
name="tlsKey"
label="Key"
value={keyPair.key}
/>
</Grid>
<Grid item xs={2} className={classes.rowActions}>
<Grid item xs={2} className={classes.rowActions}>
<div className={classes.overlayAction}>
<IconButton size={"small"} onClick={addKeyPair}>
<AddIcon />
</IconButton>
</div>
<div className={classes.overlayAction}>
<IconButton
size={"small"}
onClick={() => {
deleteKeyPair(keyPair.id);
}}
>
<RemoveIcon />
</IconButton>
</div>
</Grid>
</Grid>
))}
</Grid>
<Grid item xs={12} className={classes.minioCertsContainer}>
<SectionTitle>MinIO CA Certificates</SectionTitle>
{caCertificates.map((keyPair: KeyPair) => (
<Grid
item
xs={12}
key={`minio-CA-certs-${keyPair.id}`}
className={classes.minioCACertsRow}
>
<Grid item xs={6}>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToCaCertificates(
keyPair.id,
"cert",
fileName,
encodedValue
);
}}
accept=".cer,.crt,.cert,.pem"
id="tlsCert"
name="tlsCert"
label="Cert"
value={keyPair.cert}
/>
</Grid>
<Grid item xs={6}>
<div className={classes.rowActions}>
<div className={classes.overlayAction}>
<IconButton size={"small"} onClick={addKeyPair}>
<IconButton
size={"small"}
onClick={addCaCertificate}
>
<AddIcon />
</IconButton>
</div>
@@ -292,81 +334,22 @@ const Security = ({
<IconButton
size={"small"}
onClick={() => {
deleteKeyPair(keyPair.id);
deleteCaCertificate(keyPair.id);
}}
>
<RemoveIcon />
</IconButton>
</div>
</Grid>
</div>
</Grid>
))}
</fieldset>
</Grid>
))}
</Grid>
</Grid>
<Grid container>
<Grid item xs={12} className={classes.minioCertsContainer}>
<fieldset className={classes.fieldGroup}>
<legend className={classes.descriptionText}>
MinIO CA Certificates
</legend>
{caCertificates.map((keyPair: KeyPair) => (
<Grid
item
xs={12}
key={`minio-CA-certs-${keyPair.id}`}
className={classes.minioCACertsRow}
>
<Grid item xs={6}>
<FileSelector
onChange={(encodedValue, fileName) => {
addFileToCaCertificates(
keyPair.id,
"cert",
fileName,
encodedValue
);
}}
accept=".cer,.crt,.cert,.pem"
id="tlsCert"
name="tlsCert"
label="Cert"
value={keyPair.cert}
/>
</Grid>
<Grid item xs={6}>
<div className={classes.rowActions}>
<div className={classes.overlayAction}>
<IconButton
size={"small"}
onClick={addCaCertificate}
>
<AddIcon />
</IconButton>
</div>
<div className={classes.overlayAction}>
<IconButton
size={"small"}
onClick={() => {
deleteCaCertificate(keyPair.id);
}}
>
<RemoveIcon />
</IconButton>
</div>
</div>
</Grid>
</Grid>
))}
</fieldset>
</Grid>
</Grid>
</Fragment>
)}
</Fragment>
)}
</Fragment>
)}
</Fragment>
)}
</Grid>
</Paper>
);
};

View File

@@ -582,7 +582,7 @@ const TenantDetails = ({
}}
{{
tabConfig: {
label: "Logging",
label: "Audit Log",
value: "logging",
component: Link,
to: getRoutePath("logging"),

View File

@@ -683,28 +683,28 @@ const TenantEncryption = ({
return (
<React.Fragment>
{confirmOpen && (
<ConfirmDialog
isOpen={confirmOpen}
title={
encryptionEnabled
? "Enable encryption at rest for tenant?"
: "Disable encryption at rest for tenant?"
}
confirmText={encryptionEnabled ? "Enable" : "Disable"}
cancelText="Cancel"
onClose={() => setConfirmOpen(false)}
onConfirm={updateEncryptionConfiguration}
confirmationContent={
<DialogContentText>
{encryptionEnabled
? "Data will be encrypted using and external KMS"
: "Current encrypted information will not be accessible"}
</DialogContentText>
}
/>
)}
<Grid container spacing={1}>
{confirmOpen && (
<ConfirmDialog
isOpen={confirmOpen}
title={
encryptionEnabled
? "Enable encryption at rest for tenant?"
: "Disable encryption at rest for tenant?"
}
confirmText={encryptionEnabled ? "Enable" : "Disable"}
cancelText="Cancel"
onClose={() => setConfirmOpen(false)}
onConfirm={updateEncryptionConfiguration}
confirmationContent={
<DialogContentText>
{encryptionEnabled
? "Data will be encrypted using and external KMS"
: "Current encrypted information will not be accessible"}
</DialogContentText>
}
/>
)}
<Grid item xs>
<h1 className={classes.sectionTitle}>Encryption</h1>
</Grid>

View File

@@ -29,14 +29,13 @@ import Grid from "@mui/material/Grid";
import { DialogContentText } from "@mui/material";
import Paper from "@mui/material/Paper";
import api from "../../../../common/api";
import { ITenant } from "../ListTenants/types";
import { ITenant, ITenantLogsStruct } from "../ListTenants/types";
import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types";
import { EditIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import EditTenantLogsModal from "./EditTenantLogsModal";
import KeyPairView from "./KeyPairView";
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";
@@ -209,7 +208,7 @@ const TenantLogging = ({
)}
<Grid container alignItems={"center"}>
<Grid item xs>
<h1 className={classes.sectionTitle}>Logging</h1>
<h1 className={classes.sectionTitle}>Audit Log</h1>
</Grid>
<Grid item xs={4}>
<FormSwitchWrapper

View File

@@ -52,7 +52,7 @@ test("Create Tenant Without Audit Log", async (t) => {
.click("#confirm-ok")
.wait(1000)
.click("#wizard-step-audit-log")
.click("#log-search-enabled")
.click("#enableLogging")
.click("#wizard-button-Create")
.wait(1000)
.click("#close")