Tenant Forms alignment. Components Page. (#1811)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -19,9 +19,8 @@ import { connect } from "react-redux";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Box } from "@mui/material";
|
||||
import { Box, Grid } from "@mui/material";
|
||||
import get from "lodash/get";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { AppState } from "../../../../store";
|
||||
import { setErrorSnackMessage } from "../../../../actions";
|
||||
import {
|
||||
@@ -45,17 +44,18 @@ import api from "../../../../common/api";
|
||||
import { setBucketDetailsLoad } from "../actions";
|
||||
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
|
||||
import {
|
||||
SecureComponent,
|
||||
hasPermission,
|
||||
SecureComponent,
|
||||
} from "../../../../common/SecureComponent";
|
||||
|
||||
import withSuspense from "../../Common/Components/withSuspense";
|
||||
import LabelValuePair from "../../Common/UsageBarWrapper/LabelValuePair";
|
||||
import LabelWithIcon from "./SummaryItems/LabelWithIcon";
|
||||
import { EnabledIcon, DisabledIcon } from "../../../../icons";
|
||||
import { DisabledIcon, EnabledIcon } from "../../../../icons";
|
||||
import EditablePropertyItem from "./SummaryItems/EditablePropertyItem";
|
||||
import ReportedUsage from "./SummaryItems/ReportedUsage";
|
||||
import BucketQuotaSize from "./SummaryItems/BucketQuotaSize";
|
||||
import SectionTitle from "../../Common/SectionTitle";
|
||||
|
||||
const SetAccessPolicy = withSuspense(
|
||||
React.lazy(() => import("./SetAccessPolicy"))
|
||||
@@ -415,264 +415,247 @@ const BucketSummary = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.spacerBottom}>
|
||||
<h3
|
||||
style={{
|
||||
marginTop: "0",
|
||||
marginBottom: "0",
|
||||
}}
|
||||
<SectionTitle>Summary</SectionTitle>
|
||||
<Grid container spacing={1}>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_POLICY]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
<Box sx={{ ...twoColCssGridLayoutConfig }}>
|
||||
<Box sx={{ ...twoColCssGridLayoutConfig }}>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_POLICY]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.S3_PUT_BUCKET_POLICY]}
|
||||
resourceName={bucketName}
|
||||
property={"Access Policy:"}
|
||||
value={accessPolicy.toLowerCase()}
|
||||
onEdit={() => {
|
||||
setAccessPolicyScreenOpen(true);
|
||||
}}
|
||||
isLoading={bucketLoading}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_ENCRYPTION_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[
|
||||
IAM_SCOPES.S3_PUT_BUCKET_ENCRYPTION_CONFIGURATION,
|
||||
]}
|
||||
resourceName={bucketName}
|
||||
property={"Encryption:"}
|
||||
value={encryptionEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={() => {
|
||||
setEnableEncryptionScreenOpen(true);
|
||||
}}
|
||||
isLoading={loadingEncryption}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_REPLICATION_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<LabelValuePair
|
||||
label={"Replication:"}
|
||||
value={
|
||||
<LabelWithIcon
|
||||
icon={
|
||||
replicationRules ? <EnabledIcon /> : <DisabledIcon />
|
||||
}
|
||||
label={
|
||||
<label className={classes.textMuted}>
|
||||
{replicationRules ? "Enabled" : "Disabled"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_OBJECT_LOCK_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<LabelValuePair
|
||||
label={"Object Locking:"}
|
||||
value={
|
||||
<LabelWithIcon
|
||||
icon={
|
||||
hasObjectLocking ? <EnabledIcon /> : <DisabledIcon />
|
||||
}
|
||||
label={
|
||||
<label className={classes.textMuted}>
|
||||
{hasObjectLocking ? "Enabled" : "Disabled"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<Box className={classes.spacerTop}>
|
||||
<LabelValuePair
|
||||
label={"Tags:"}
|
||||
value={
|
||||
<BucketTags
|
||||
setErrorSnackMessage={setErrorSnackMessage}
|
||||
bucketName={bucketName}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
<ReportedUsage bucketSize={bucketSize} />
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</SecureComponent>
|
||||
|
||||
{distributedSetup && (
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_VERSIONING]}
|
||||
resource={bucketName}
|
||||
>
|
||||
Summary
|
||||
</h3>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Versioning</SectionTitle>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
...twoColCssGridLayoutConfig,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
...twoColCssGridLayoutConfig,
|
||||
}}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.S3_PUT_BUCKET_VERSIONING]}
|
||||
resourceName={bucketName}
|
||||
property={"Versioning:"}
|
||||
value={isVersioned ? "Enabled" : "Disabled"}
|
||||
onEdit={setBucketVersioning}
|
||||
isLoading={loadingVersioning}
|
||||
/>
|
||||
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.ADMIN_SET_BUCKET_QUOTA]}
|
||||
resourceName={bucketName}
|
||||
property={"Quota:"}
|
||||
value={quotaEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={setBucketQuota}
|
||||
isLoading={loadingQuota}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
{quotaEnabled && quota ? (
|
||||
<BucketQuotaSize quota={quota} />
|
||||
) : null}
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</SecureComponent>
|
||||
)}
|
||||
|
||||
{hasObjectLocking && (
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_OBJECT_RETENTION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Retention</SectionTitle>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", sm: "2fr 1fr" },
|
||||
gridAutoFlow: { xs: "dense", sm: "row" } /* NEW */,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", sm: "2fr 1fr" },
|
||||
gridAutoFlow: { xs: "dense", sm: "row" } /* NEW */,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.ADMIN_SET_BUCKET_QUOTA]}
|
||||
resourceName={bucketName}
|
||||
property={"Retention:"}
|
||||
value={retentionEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={() => {
|
||||
setRetentionConfigOpen(true);
|
||||
}}
|
||||
isLoading={loadingRetention}
|
||||
/>
|
||||
|
||||
<LabelValuePair
|
||||
label={"Mode:"}
|
||||
value={
|
||||
<label
|
||||
className={classes.textMuted}
|
||||
style={{ textTransform: "capitalize" }}
|
||||
>
|
||||
{retentionConfig && retentionConfig.mode
|
||||
? retentionConfig.mode
|
||||
: "-"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
<LabelValuePair
|
||||
label={"Validity:"}
|
||||
value={
|
||||
<label
|
||||
className={classes.textMuted}
|
||||
style={{ textTransform: "capitalize" }}
|
||||
>
|
||||
{retentionConfig && retentionConfig.validity}{" "}
|
||||
{retentionConfig &&
|
||||
(retentionConfig.validity === 1
|
||||
? retentionConfig.unit.slice(0, -1)
|
||||
: retentionConfig.unit)}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
{/*Spacer*/}
|
||||
</Box>
|
||||
</Box>
|
||||
</Grid>
|
||||
</SecureComponent>
|
||||
)}
|
||||
</Grid>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_POLICY]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<Box sx={{ ...twoColCssGridLayoutConfig }}>
|
||||
<Box sx={{ ...twoColCssGridLayoutConfig }}>
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_POLICY]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.S3_PUT_BUCKET_POLICY]}
|
||||
resourceName={bucketName}
|
||||
property={"Access Policy:"}
|
||||
value={accessPolicy.toLowerCase()}
|
||||
onEdit={() => {
|
||||
setAccessPolicyScreenOpen(true);
|
||||
}}
|
||||
isLoading={bucketLoading}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_ENCRYPTION_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.S3_PUT_BUCKET_ENCRYPTION_CONFIGURATION]}
|
||||
resourceName={bucketName}
|
||||
property={"Encryption:"}
|
||||
value={encryptionEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={() => {
|
||||
setEnableEncryptionScreenOpen(true);
|
||||
}}
|
||||
isLoading={loadingEncryption}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_REPLICATION_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<LabelValuePair
|
||||
label={"Replication:"}
|
||||
value={
|
||||
<LabelWithIcon
|
||||
icon={replicationRules ? <EnabledIcon /> : <DisabledIcon />}
|
||||
label={
|
||||
<label className={classes.textMuted}>
|
||||
{replicationRules ? "Enabled" : "Disabled"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</SecureComponent>
|
||||
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_OBJECT_LOCK_CONFIGURATION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<LabelValuePair
|
||||
label={"Object Locking:"}
|
||||
value={
|
||||
<LabelWithIcon
|
||||
icon={hasObjectLocking ? <EnabledIcon /> : <DisabledIcon />}
|
||||
label={
|
||||
<label className={classes.textMuted}>
|
||||
{hasObjectLocking ? "Enabled" : "Disabled"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</SecureComponent>
|
||||
<Box className={classes.spacerTop}>
|
||||
<LabelValuePair
|
||||
label={"Tags:"}
|
||||
value={
|
||||
<BucketTags
|
||||
setErrorSnackMessage={setErrorSnackMessage}
|
||||
bucketName={bucketName}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
<ReportedUsage bucketSize={bucketSize} />
|
||||
</Box>
|
||||
</Box>
|
||||
</SecureComponent>
|
||||
|
||||
{distributedSetup && (
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_BUCKET_VERSIONING]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.spacerBottom}>
|
||||
<h3
|
||||
style={{
|
||||
marginTop: "25px",
|
||||
marginBottom: "0",
|
||||
}}
|
||||
>
|
||||
Versioning
|
||||
</h3>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
...twoColCssGridLayoutConfig,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
...twoColCssGridLayoutConfig,
|
||||
}}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.S3_PUT_BUCKET_VERSIONING]}
|
||||
resourceName={bucketName}
|
||||
property={"Versioning:"}
|
||||
value={isVersioned ? "Enabled" : "Disabled"}
|
||||
onEdit={setBucketVersioning}
|
||||
isLoading={loadingVersioning}
|
||||
/>
|
||||
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.ADMIN_SET_BUCKET_QUOTA]}
|
||||
resourceName={bucketName}
|
||||
property={"Quota:"}
|
||||
value={quotaEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={setBucketQuota}
|
||||
isLoading={loadingQuota}
|
||||
/>
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
{quotaEnabled && quota ? <BucketQuotaSize quota={quota} /> : null}
|
||||
</Box>
|
||||
</Box>
|
||||
</SecureComponent>
|
||||
)}
|
||||
|
||||
{hasObjectLocking && (
|
||||
<SecureComponent
|
||||
scopes={[IAM_SCOPES.S3_GET_OBJECT_RETENTION]}
|
||||
resource={bucketName}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.spacerBottom}>
|
||||
<h3
|
||||
style={{
|
||||
marginTop: "25px",
|
||||
marginBottom: "0",
|
||||
}}
|
||||
>
|
||||
Retention
|
||||
</h3>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", sm: "2fr 1fr" },
|
||||
gridAutoFlow: { xs: "dense", sm: "row" } /* NEW */,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: { xs: "1fr", sm: "2fr 1fr" },
|
||||
gridAutoFlow: { xs: "dense", sm: "row" } /* NEW */,
|
||||
gap: 2,
|
||||
}}
|
||||
>
|
||||
<EditablePropertyItem
|
||||
iamScopes={[IAM_SCOPES.ADMIN_SET_BUCKET_QUOTA]}
|
||||
resourceName={bucketName}
|
||||
property={"Retention:"}
|
||||
value={retentionEnabled ? "Enabled" : "Disabled"}
|
||||
onEdit={() => {
|
||||
setRetentionConfigOpen(true);
|
||||
}}
|
||||
isLoading={loadingRetention}
|
||||
/>
|
||||
|
||||
<LabelValuePair
|
||||
label={"Mode:"}
|
||||
value={
|
||||
<label
|
||||
className={classes.textMuted}
|
||||
style={{ textTransform: "capitalize" }}
|
||||
>
|
||||
{retentionConfig && retentionConfig.mode
|
||||
? retentionConfig.mode
|
||||
: "-"}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
<LabelValuePair
|
||||
label={"Validity:"}
|
||||
value={
|
||||
<label
|
||||
className={classes.textMuted}
|
||||
style={{ textTransform: "capitalize" }}
|
||||
>
|
||||
{retentionConfig && retentionConfig.validity}{" "}
|
||||
{retentionConfig &&
|
||||
(retentionConfig.validity === 1
|
||||
? retentionConfig.unit.slice(0, -1)
|
||||
: retentionConfig.unit)}
|
||||
</label>
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr",
|
||||
alignItems: "flex-start",
|
||||
}}
|
||||
>
|
||||
{/*Spacer*/}
|
||||
</Box>
|
||||
</Box>
|
||||
</SecureComponent>
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
258
portal-ui/src/screens/Console/Common/ComponentsScreen.tsx
Normal file
258
portal-ui/src/screens/Console/Common/ComponentsScreen.tsx
Normal file
@@ -0,0 +1,258 @@
|
||||
// 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, { Fragment, useState } from "react";
|
||||
import { containerForHeader } from "../Common/FormComponents/common/styleLibrary";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Button, DialogContentText, Grid } from "@mui/material";
|
||||
import PageHeader from "./PageHeader/PageHeader";
|
||||
import PageLayout from "./Layout/PageLayout";
|
||||
import SectionTitle from "./SectionTitle";
|
||||
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
|
||||
import {
|
||||
ArrowIcon,
|
||||
ConfirmDeleteIcon,
|
||||
EditIcon,
|
||||
TrashIcon,
|
||||
} from "../../../icons";
|
||||
import ConfirmDialog from "./ModalWrapper/ConfirmDialog";
|
||||
|
||||
interface IComponentsScreen {
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
root: {
|
||||
fontSize: 12,
|
||||
wordWrap: "break-word",
|
||||
"& .min-loader": {
|
||||
width: 45,
|
||||
height: 45,
|
||||
},
|
||||
},
|
||||
def: {},
|
||||
red: {
|
||||
"& .min-icon": {
|
||||
color: "red",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const ComponentsScreen = ({ classes }: IComponentsScreen) => {
|
||||
const [dialogOpen, setDialogOpen] = useState<boolean>(false);
|
||||
return (
|
||||
<Fragment>
|
||||
<PageHeader label={"Components"} />
|
||||
<PageLayout>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Buttons</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<p>Buttons should always be of one of the following four types:</p>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item>
|
||||
<Button
|
||||
type="button"
|
||||
variant={"contained"}
|
||||
className={classes.clearButton}
|
||||
onClick={() => {}}
|
||||
>
|
||||
Primary
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => {}}
|
||||
disabled={true}
|
||||
>
|
||||
Primary Disabled
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button type="button" variant={"outlined"} onClick={() => {}}>
|
||||
Generic
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
type="button"
|
||||
variant={"outlined"}
|
||||
onClick={() => {}}
|
||||
disabled={true}
|
||||
>
|
||||
Generic Disabled
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
type="button"
|
||||
variant={"outlined"}
|
||||
color={"secondary"}
|
||||
onClick={() => {}}
|
||||
>
|
||||
Dangerous
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
type="button"
|
||||
variant={"outlined"}
|
||||
color={"secondary"}
|
||||
onClick={() => {}}
|
||||
disabled={true}
|
||||
>
|
||||
Dangerous Disabled
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<ul>
|
||||
<li>
|
||||
<b>Primary:</b> A call to action.
|
||||
</li>
|
||||
<li>
|
||||
<b>Generic:</b> An optional action.
|
||||
</li>
|
||||
<li>
|
||||
<b>Dangerous:</b> An irreversible action.
|
||||
</li>
|
||||
</ul>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Icon Buttons</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<p>Icon Buttons should always be of one of the following types:</p>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Primary"}
|
||||
onClick={() => {}}
|
||||
text={"Primary"}
|
||||
icon={<ArrowIcon />}
|
||||
color={"primary"}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Primary Disabled"}
|
||||
onClick={() => {}}
|
||||
text={"Primary Disabled"}
|
||||
icon={<ArrowIcon />}
|
||||
color={"primary"}
|
||||
variant={"outlined"}
|
||||
disabled={true}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Delete Bucket"}
|
||||
onClick={() => {}}
|
||||
text={"Generic"}
|
||||
icon={<EditIcon />}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Delete Bucket"}
|
||||
onClick={() => {}}
|
||||
text={"Generic Disabled"}
|
||||
icon={<EditIcon />}
|
||||
variant={"outlined"}
|
||||
disabled={true}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Dangerous"}
|
||||
onClick={() => {}}
|
||||
text={"Dangerous"}
|
||||
icon={<TrashIcon />}
|
||||
color={"secondary"}
|
||||
variant={"outlined"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<RBIconButton
|
||||
tooltip={"Dangerous"}
|
||||
onClick={() => {}}
|
||||
text={"Dangerous Disabled"}
|
||||
icon={<TrashIcon />}
|
||||
color={"secondary"}
|
||||
variant={"outlined"}
|
||||
disabled={true}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Confirm Dialogs</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<p>Used to confirm a non-idempotent action.</p>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Button
|
||||
type="button"
|
||||
variant={"outlined"}
|
||||
onClick={() => {
|
||||
setDialogOpen(true);
|
||||
}}
|
||||
>
|
||||
Open Dialog
|
||||
</Button>
|
||||
<ConfirmDialog
|
||||
title={`Delete Bucket`}
|
||||
confirmText={"Delete"}
|
||||
isOpen={dialogOpen}
|
||||
titleIcon={<ConfirmDeleteIcon />}
|
||||
isLoading={false}
|
||||
onConfirm={() => {
|
||||
setDialogOpen(false);
|
||||
}}
|
||||
onClose={() => {
|
||||
setDialogOpen(false);
|
||||
}}
|
||||
confirmationContent={
|
||||
<DialogContentText>
|
||||
Are you sure you want to delete bucket <b>bucket</b>
|
||||
? <br />A bucket can only be deleted if it's empty.
|
||||
</DialogContentText>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</PageLayout>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(ComponentsScreen);
|
||||
54
portal-ui/src/screens/Console/Common/SectionTitle.tsx
Normal file
54
portal-ui/src/screens/Console/Common/SectionTitle.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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";
|
||||
import Grid from "@mui/material/Grid";
|
||||
|
||||
type Props = {
|
||||
separator?: boolean;
|
||||
actions?: React.ReactNode;
|
||||
};
|
||||
|
||||
const SectionTitle: React.FC<Props> = ({
|
||||
children,
|
||||
separator = true,
|
||||
actions,
|
||||
}) => {
|
||||
return (
|
||||
<Grid
|
||||
container
|
||||
alignItems={"center"}
|
||||
justifyContent="space-between"
|
||||
sx={{
|
||||
borderBottom: separator ? "1px solid #eaeaea" : "",
|
||||
}}
|
||||
>
|
||||
<Grid item xs>
|
||||
<h3
|
||||
style={{
|
||||
margin: 0,
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</h3>
|
||||
</Grid>
|
||||
{actions && <Grid item> {actions}</Grid>}
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionTitle;
|
||||
@@ -51,6 +51,7 @@ import { hasPermission } from "../../common/SecureComponent";
|
||||
import { IRouteRule } from "./Menu/types";
|
||||
import LoadingComponent from "../../common/LoadingComponent";
|
||||
import EditPool from "./Tenants/TenantDetails/Pools/EditPool/EditPool";
|
||||
import ComponentsScreen from "./Common/ComponentsScreen";
|
||||
|
||||
const Trace = React.lazy(() => import("./Trace/Trace"));
|
||||
const Heal = React.lazy(() => import("./Heal/Heal"));
|
||||
@@ -613,6 +614,11 @@ const Console = ({
|
||||
<IconsScreen />
|
||||
</Suspense>
|
||||
</Route>
|
||||
<Route key={"/components"} exact path={"/components"}>
|
||||
<Suspense fallback={<LoadingComponent />}>
|
||||
<ComponentsScreen />
|
||||
</Suspense>
|
||||
</Route>
|
||||
{allowedRoutes.length > 0 ? (
|
||||
<Redirect to={allowedRoutes[0].path} />
|
||||
) : null}
|
||||
|
||||
@@ -489,9 +489,7 @@ const PolicyDetails = ({
|
||||
variant="standard"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<br />
|
||||
</Grid>
|
||||
|
||||
<TableWrapper
|
||||
itemActions={userTableActions}
|
||||
columns={[{ label: "Name", elementKey: "name" }]}
|
||||
@@ -533,9 +531,6 @@ const PolicyDetails = ({
|
||||
variant="standard"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<br />
|
||||
</Grid>
|
||||
<TableWrapper
|
||||
itemActions={groupTableActions}
|
||||
columns={[{ label: "Name", elementKey: "name" }]}
|
||||
|
||||
@@ -45,7 +45,7 @@ import Grid from "@mui/material/Grid";
|
||||
import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
|
||||
import { Button, DialogContentText, Stack } from "@mui/material";
|
||||
import { Button, DialogContentText } from "@mui/material";
|
||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import { KeyPair } from "../ListTenants/utils";
|
||||
@@ -56,7 +56,7 @@ import {
|
||||
} from "../../../../utils/validationFunctions";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate";
|
||||
import StackRow from "../../Common/UsageBarWrapper/StackRow";
|
||||
import SectionTitle from "../../Common/SectionTitle";
|
||||
|
||||
interface ITenantEncryption {
|
||||
classes: any;
|
||||
@@ -683,7 +683,7 @@ const TenantEncryption = ({
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Fragment>
|
||||
<Grid container spacing={1}>
|
||||
{confirmOpen && (
|
||||
<ConfirmDialog
|
||||
isOpen={confirmOpen}
|
||||
@@ -705,33 +705,28 @@ const TenantEncryption = ({
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Grid container alignItems={"center"}>
|
||||
<Grid item xs>
|
||||
<h1 className={classes.sectionTitle}>Encryption</h1>
|
||||
</Grid>
|
||||
<Grid
|
||||
item
|
||||
xs={4}
|
||||
justifyContent={"end"}
|
||||
textAlign={"right"}
|
||||
className={classes.formFieldRow}
|
||||
>
|
||||
<FormSwitchWrapper
|
||||
label={""}
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
checked={encryptionEnabled}
|
||||
value={"tenant_encryption"}
|
||||
id="tenant-encryption"
|
||||
name="tenant-encryption"
|
||||
onChange={() => {
|
||||
setEncryptionEnabled(!encryptionEnabled);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<h1 className={classes.sectionTitle}>Encryption</h1>
|
||||
</Grid>
|
||||
<Grid item xs={4} justifyContent={"end"} textAlign={"right"}>
|
||||
<FormSwitchWrapper
|
||||
label={""}
|
||||
indicatorLabels={["Enabled", "Disabled"]}
|
||||
checked={encryptionEnabled}
|
||||
value={"tenant_encryption"}
|
||||
id="tenant-encryption"
|
||||
name="tenant-encryption"
|
||||
onChange={() => {
|
||||
setEncryptionEnabled(!encryptionEnabled);
|
||||
}}
|
||||
description=""
|
||||
/>
|
||||
</Grid>
|
||||
<Grid xs={12}>
|
||||
<hr className={classes.hrClass} />
|
||||
</Grid>
|
||||
{encryptionEnabled && (
|
||||
<Grid container spacing={1}>
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.encryptionTypeOptions}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={encryptionType}
|
||||
@@ -752,7 +747,7 @@ const TenantEncryption = ({
|
||||
</Grid>
|
||||
{encryptionType === "vault" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_endpoint"
|
||||
name="vault_endpoint"
|
||||
@@ -768,7 +763,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_engine"
|
||||
name="vault_engine"
|
||||
@@ -782,7 +777,7 @@ const TenantEncryption = ({
|
||||
value={vaultConfiguration?.engine || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_namespace"
|
||||
name="vault_namespace"
|
||||
@@ -796,7 +791,7 @@ const TenantEncryption = ({
|
||||
value={vaultConfiguration?.namespace || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_prefix"
|
||||
name="vault_prefix"
|
||||
@@ -810,142 +805,110 @@ const TenantEncryption = ({
|
||||
value={vaultConfiguration?.prefix || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
marginBottom: 1,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
App Role
|
||||
</h3>
|
||||
</StackRow>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_approle_engine"
|
||||
name="vault_approle_engine"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
engine: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Engine"
|
||||
value={vaultConfiguration?.approle?.engine || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type={showVaultAppRoleID ? "text" : "password"}
|
||||
id="vault_id"
|
||||
name="vault_id"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
id: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="AppRole ID"
|
||||
value={vaultConfiguration?.approle?.id || ""}
|
||||
required
|
||||
error={validationErrors["vault_id"] || ""}
|
||||
overlayIcon={
|
||||
showVaultAppRoleID ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowVaultAppRoleID(!showVaultAppRoleID)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type={showVaultAppRoleSecret ? "text" : "password"}
|
||||
id="vault_secret"
|
||||
name="vault_secret"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
secret: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="AppRole Secret"
|
||||
value={vaultConfiguration?.approle?.secret || ""}
|
||||
required
|
||||
error={validationErrors["vault_secret"] || ""}
|
||||
overlayIcon={
|
||||
showVaultAppRoleSecret ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowVaultAppRoleSecret(!showVaultAppRoleSecret)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="0"
|
||||
id="vault_retry"
|
||||
name="vault_retry"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
retry: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Retry (Seconds)"
|
||||
error={validationErrors["vault_retry"] || ""}
|
||||
value={vaultConfiguration?.approle?.retry || ""}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Stack>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>App Role</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
marginBottom: 1,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Vault Certificates (optional)
|
||||
</h3>
|
||||
</StackRow>
|
||||
</Stack>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="vault_approle_engine"
|
||||
name="vault_approle_engine"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
engine: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Engine"
|
||||
value={vaultConfiguration?.approle?.engine || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type={showVaultAppRoleID ? "text" : "password"}
|
||||
id="vault_id"
|
||||
name="vault_id"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
id: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="AppRole ID"
|
||||
value={vaultConfiguration?.approle?.id || ""}
|
||||
required
|
||||
error={validationErrors["vault_id"] || ""}
|
||||
overlayIcon={
|
||||
showVaultAppRoleID ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowVaultAppRoleID(!showVaultAppRoleID)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type={showVaultAppRoleSecret ? "text" : "password"}
|
||||
id="vault_secret"
|
||||
name="vault_secret"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
secret: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="AppRole Secret"
|
||||
value={vaultConfiguration?.approle?.secret || ""}
|
||||
required
|
||||
error={validationErrors["vault_secret"] || ""}
|
||||
overlayIcon={
|
||||
showVaultAppRoleSecret ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowVaultAppRoleSecret(!showVaultAppRoleSecret)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="0"
|
||||
id="vault_retry"
|
||||
name="vault_retry"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
approle: {
|
||||
...vaultConfiguration?.approle,
|
||||
retry: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Retry (Seconds)"
|
||||
error={validationErrors["vault_retry"] || ""}
|
||||
value={vaultConfiguration?.approle?.retry || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Vault Certificates (optional)</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Mutual TLS authentication with Vault (optional)
|
||||
@@ -1027,48 +990,34 @@ const TenantEncryption = ({
|
||||
)}
|
||||
</fieldset>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
marginBottom: 1,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Status
|
||||
</h3>
|
||||
</StackRow>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="0"
|
||||
id="vault_ping"
|
||||
name="vault_ping"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
status: {
|
||||
...vaultConfiguration?.status,
|
||||
ping: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Ping (Seconds)"
|
||||
error={validationErrors["vault_ping"] || ""}
|
||||
value={vaultConfiguration?.status?.ping || ""}
|
||||
/>
|
||||
</Stack>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Status</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="0"
|
||||
id="vault_ping"
|
||||
name="vault_ping"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
setVaultConfiguration({
|
||||
...vaultConfiguration,
|
||||
status: {
|
||||
...vaultConfiguration?.status,
|
||||
ping: e.target.value,
|
||||
},
|
||||
})
|
||||
}
|
||||
label="Ping (Seconds)"
|
||||
error={validationErrors["vault_ping"] || ""}
|
||||
value={vaultConfiguration?.status?.ping || ""}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
{encryptionType === "azure" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="azure_endpoint"
|
||||
name="azure_endpoint"
|
||||
@@ -1086,12 +1035,12 @@ const TenantEncryption = ({
|
||||
value={azureConfiguration?.keyvault?.endpoint || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Credentials
|
||||
</legend>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="azure_tenant_id"
|
||||
name="azure_tenant_id"
|
||||
@@ -1115,7 +1064,7 @@ const TenantEncryption = ({
|
||||
error={validationErrors["azure_tenant_id"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="azure_client_id"
|
||||
name="azure_client_id"
|
||||
@@ -1139,7 +1088,7 @@ const TenantEncryption = ({
|
||||
error={validationErrors["azure_client_id"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="azure_client_secret"
|
||||
name="azure_client_secret"
|
||||
@@ -1169,7 +1118,7 @@ const TenantEncryption = ({
|
||||
)}
|
||||
{encryptionType === "gcp" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_project_id"
|
||||
name="gcp_project_id"
|
||||
@@ -1186,7 +1135,7 @@ const TenantEncryption = ({
|
||||
value={gcpConfiguration?.secretmanager.project_id || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_endpoint"
|
||||
name="gcp_endpoint"
|
||||
@@ -1203,12 +1152,12 @@ const TenantEncryption = ({
|
||||
value={gcpConfiguration?.secretmanager.endpoint || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Credentials
|
||||
</legend>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_client_email"
|
||||
name="gcp_client_email"
|
||||
@@ -1231,7 +1180,7 @@ const TenantEncryption = ({
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_client_id"
|
||||
name="gcp_client_id"
|
||||
@@ -1254,7 +1203,7 @@ const TenantEncryption = ({
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_private_key_id"
|
||||
name="gcp_private_key_id"
|
||||
@@ -1277,7 +1226,7 @@ const TenantEncryption = ({
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gcp_private_key"
|
||||
name="gcp_private_key"
|
||||
@@ -1306,7 +1255,7 @@ const TenantEncryption = ({
|
||||
)}
|
||||
{encryptionType === "aws" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_endpoint"
|
||||
name="aws_endpoint"
|
||||
@@ -1325,7 +1274,7 @@ const TenantEncryption = ({
|
||||
error={validationErrors["aws_endpoint"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_region"
|
||||
name="aws_region"
|
||||
@@ -1344,7 +1293,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_kmsKey"
|
||||
name="aws_kmsKey"
|
||||
@@ -1361,12 +1310,12 @@ const TenantEncryption = ({
|
||||
value={awsConfiguration?.secretsmanager?.kmskey || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Credentials
|
||||
</legend>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_accessKey"
|
||||
name="aws_accessKey"
|
||||
@@ -1392,7 +1341,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_secretKey"
|
||||
name="aws_secretKey"
|
||||
@@ -1418,7 +1367,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="aws_token"
|
||||
name="aws_token"
|
||||
@@ -1448,7 +1397,7 @@ const TenantEncryption = ({
|
||||
)}
|
||||
{encryptionType === "gemalto" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gemalto_endpoint"
|
||||
name="gemalto_endpoint"
|
||||
@@ -1473,13 +1422,12 @@ const TenantEncryption = ({
|
||||
style={{
|
||||
marginBottom: 15,
|
||||
}}
|
||||
className={classes.formFieldRow}
|
||||
>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Credentials
|
||||
</legend>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gemalto_token"
|
||||
name="gemalto_token"
|
||||
@@ -1504,7 +1452,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
id="gemalto_domain"
|
||||
name="gemalto_domain"
|
||||
@@ -1529,7 +1477,7 @@ const TenantEncryption = ({
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="0"
|
||||
@@ -1563,7 +1511,6 @@ const TenantEncryption = ({
|
||||
style={{
|
||||
marginBottom: 15,
|
||||
}}
|
||||
className={classes.formFieldRow}
|
||||
>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
@@ -1599,39 +1546,24 @@ const TenantEncryption = ({
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
marginBottom: 1,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
Additional Configuration for KES
|
||||
</h3>
|
||||
</StackRow>
|
||||
|
||||
<FormSwitchWrapper
|
||||
value="enableCustomCertsForKES"
|
||||
id="enableCustomCertsForKES"
|
||||
name="enableCustomCertsForKES"
|
||||
checked={enabledCustomCertificates}
|
||||
onChange={() =>
|
||||
setEnabledCustomCertificates(!enabledCustomCertificates)
|
||||
}
|
||||
label={"Custom Certificates"}
|
||||
/>
|
||||
</Stack>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>Additional Configuration for KES</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="enableCustomCertsForKES"
|
||||
id="enableCustomCertsForKES"
|
||||
name="enableCustomCertsForKES"
|
||||
checked={enabledCustomCertificates}
|
||||
onChange={() =>
|
||||
setEnabledCustomCertificates(!enabledCustomCertificates)
|
||||
}
|
||||
label={"Custom Certificates"}
|
||||
/>
|
||||
</Grid>
|
||||
{enabledCustomCertificates && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
KES server TLS Certificates (optional)
|
||||
@@ -1684,7 +1616,7 @@ const TenantEncryption = ({
|
||||
)}
|
||||
</fieldset>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<fieldset className={classes.fieldGroup}>
|
||||
<legend className={classes.descriptionText}>
|
||||
Mutual TLS authentication with MinIO (optional)
|
||||
@@ -1738,7 +1670,7 @@ const TenantEncryption = ({
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="text"
|
||||
id="image"
|
||||
@@ -1751,7 +1683,7 @@ const TenantEncryption = ({
|
||||
value={image}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
min="1"
|
||||
@@ -1766,120 +1698,101 @@ const TenantEncryption = ({
|
||||
error={validationErrors["replicas"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
marginBottom: 1,
|
||||
}}
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>SecurityContext for KES</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<div
|
||||
className={`${classes.multiContainer} ${classes.responsiveContainer}`}
|
||||
>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
SecurityContext for KES
|
||||
</h3>
|
||||
</StackRow>
|
||||
<Grid item xs={12} className={classes.kesSecurityContext}>
|
||||
<div
|
||||
className={`${classes.multiContainer} ${classes.responsiveContainer}`}
|
||||
>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_runAsUser"
|
||||
name="kes_securityContext_runAsUser"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
runAsUser: e.target.value,
|
||||
});
|
||||
}}
|
||||
label="Run As User"
|
||||
value={securityContext.runAsUser}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_runAsUser"] ||
|
||||
""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_runAsGroup"
|
||||
name="kes_securityContext_runAsGroup"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
runAsGroup: e.target.value,
|
||||
});
|
||||
}}
|
||||
label="Run As Group"
|
||||
value={securityContext.runAsGroup}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_runAsGroup"] ||
|
||||
""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_fsGroup"
|
||||
name="kes_securityContext_fsGroup"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
fsGroup: e.target.value,
|
||||
});
|
||||
}}
|
||||
label="FsGroup"
|
||||
value={securityContext.fsGroup}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_fsGroup"] || ""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
<br />
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="kesSecurityContextRunAsNonRoot"
|
||||
id="kes_securityContext_runAsNonRoot"
|
||||
name="kes_securityContext_runAsNonRoot"
|
||||
checked={securityContext.runAsNonRoot}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_runAsUser"
|
||||
name="kes_securityContext_runAsUser"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
runAsNonRoot: checked,
|
||||
runAsUser: e.target.value,
|
||||
});
|
||||
}}
|
||||
label={"Do not run as Root"}
|
||||
label="Run As User"
|
||||
value={securityContext.runAsUser}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_runAsUser"] || ""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</div>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_runAsGroup"
|
||||
name="kes_securityContext_runAsGroup"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
runAsGroup: e.target.value,
|
||||
});
|
||||
}}
|
||||
label="Run As Group"
|
||||
value={securityContext.runAsGroup}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_runAsGroup"] || ""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={`${classes.formFieldRow} ${classes.rightSpacer}`}
|
||||
>
|
||||
<InputBoxWrapper
|
||||
type="number"
|
||||
id="kes_securityContext_fsGroup"
|
||||
name="kes_securityContext_fsGroup"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
fsGroup: e.target.value,
|
||||
});
|
||||
}}
|
||||
label="FsGroup"
|
||||
value={securityContext.fsGroup}
|
||||
required
|
||||
error={
|
||||
validationErrors["kes_securityContext_fsGroup"] || ""
|
||||
}
|
||||
min="0"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="kesSecurityContextRunAsNonRoot"
|
||||
id="kes_securityContext_runAsNonRoot"
|
||||
name="kes_securityContext_runAsNonRoot"
|
||||
checked={securityContext.runAsNonRoot}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setSecurityContext({
|
||||
...securityContext,
|
||||
runAsNonRoot: checked,
|
||||
});
|
||||
}}
|
||||
label={"Do not run as Root"}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Grid item xs={12} textAlign={"right"}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
@@ -1890,7 +1803,7 @@ const TenantEncryption = ({
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
tenantDetailsStyles,
|
||||
wizardCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
||||
import { Button, DialogContentText, Typography } from "@mui/material";
|
||||
@@ -50,6 +49,7 @@ import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
|
||||
import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import { ConfirmModalIcon } from "../../../../icons";
|
||||
|
||||
interface ITenantIdentityProvider {
|
||||
classes: any;
|
||||
loadingTenant: boolean;
|
||||
@@ -298,304 +298,302 @@ const TenantIdentityProvider = ({
|
||||
}
|
||||
/>
|
||||
{loadingTenant ? (
|
||||
<Paper className={classes.paperContainer}>
|
||||
<div className={classes.loaderAlign}>
|
||||
<Loader />
|
||||
</div>
|
||||
</Paper>
|
||||
<div className={classes.loaderAlign}>
|
||||
<Loader />
|
||||
</div>
|
||||
) : (
|
||||
<Fragment>
|
||||
<h1 className={classes.sectionTitle}>Identity Provider</h1>
|
||||
<Paper className={classes.paperContainer}>
|
||||
<Grid item xs={12} className={classes.protocolRadioOptions}>
|
||||
<label>Protocol</label>
|
||||
<RadioGroupSelector
|
||||
currentSelection={idpSelection}
|
||||
id="idp-options"
|
||||
name="idp-options"
|
||||
label=" "
|
||||
onChange={(e) => {
|
||||
setIdpSelection(e.target.value);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ label: "Built-in", value: "Built-in" },
|
||||
{ label: "OpenID", value: "OpenID" },
|
||||
{ label: "Active Directory", value: "AD" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<h1 className={classes.sectionTitle}>Identity Provider</h1>
|
||||
<hr className={classes.hrClass} />
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.protocolRadioOptions}>
|
||||
<RadioGroupSelector
|
||||
currentSelection={idpSelection}
|
||||
id="idp-options"
|
||||
name="idp-options"
|
||||
label="Protocol"
|
||||
onChange={(e) => {
|
||||
setIdpSelection(e.target.value);
|
||||
}}
|
||||
selectorOptions={[
|
||||
{ label: "Built-in", value: "Built-in" },
|
||||
{ label: "OpenID", value: "OpenID" },
|
||||
{ label: "Active Directory", value: "AD" },
|
||||
]}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{idpSelection === "OpenID" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_CONFIGURATION_URL"
|
||||
name="openID_CONFIGURATION_URL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDConfigurationURL(e.target.value);
|
||||
cleanValidation("openID_CONFIGURATION_URL");
|
||||
}}
|
||||
label="Configuration URL"
|
||||
value={openIDConfigurationURL}
|
||||
placeholder="https://your-identity-provider.com/.well-known/openid-configuration"
|
||||
error={validationErrors["openID_CONFIGURATION_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_clientID"
|
||||
name="openID_clientID"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDClientID(e.target.value);
|
||||
cleanValidation("openID_clientID");
|
||||
}}
|
||||
label="Client ID"
|
||||
value={openIDClientID}
|
||||
error={validationErrors["openID_clientID"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
type={showOIDCSecretID ? "text" : "password"}
|
||||
id="openID_secretID"
|
||||
name="openID_secretID"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDSecretID(e.target.value);
|
||||
cleanValidation("openID_secretID");
|
||||
}}
|
||||
label="Secret ID"
|
||||
value={openIDSecretID}
|
||||
error={validationErrors["openID_secretID"] || ""}
|
||||
required
|
||||
overlayIcon={
|
||||
showOIDCSecretID ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() => setShowOIDCSecretID(!showOIDCSecretID)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_callbackURL"
|
||||
name="openID_callbackURL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDCallbackURL(e.target.value);
|
||||
cleanValidation("openID_callbackURL");
|
||||
}}
|
||||
label="Callback URL"
|
||||
value={openIDCallbackURL}
|
||||
placeholder="https://your-console-endpoint:9443/oauth_callback"
|
||||
error={validationErrors["openID_callbackURL"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_claimName"
|
||||
name="openID_claimName"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDClaimName(e.target.value);
|
||||
cleanValidation("openID_claimName");
|
||||
}}
|
||||
label="Claim Name"
|
||||
value={openIDClaimName}
|
||||
error={validationErrors["openID_claimName"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_scopes"
|
||||
name="openID_scopes"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDScopes(e.target.value);
|
||||
cleanValidation("openID_scopes");
|
||||
}}
|
||||
label="Scopes"
|
||||
value={openIDScopes}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
{idpSelection === "OpenID" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_CONFIGURATION_URL"
|
||||
name="openID_CONFIGURATION_URL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDConfigurationURL(e.target.value);
|
||||
cleanValidation("openID_CONFIGURATION_URL");
|
||||
}}
|
||||
label="Configuration URL"
|
||||
value={openIDConfigurationURL}
|
||||
placeholder="https://your-identity-provider.com/.well-known/openid-configuration"
|
||||
error={validationErrors["openID_CONFIGURATION_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_clientID"
|
||||
name="openID_clientID"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDClientID(e.target.value);
|
||||
cleanValidation("openID_clientID");
|
||||
}}
|
||||
label="Client ID"
|
||||
value={openIDClientID}
|
||||
error={validationErrors["openID_clientID"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
type={showOIDCSecretID ? "text" : "password"}
|
||||
id="openID_secretID"
|
||||
name="openID_secretID"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDSecretID(e.target.value);
|
||||
cleanValidation("openID_secretID");
|
||||
}}
|
||||
label="Secret ID"
|
||||
value={openIDSecretID}
|
||||
error={validationErrors["openID_secretID"] || ""}
|
||||
required
|
||||
overlayIcon={
|
||||
showOIDCSecretID ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() => setShowOIDCSecretID(!showOIDCSecretID)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_callbackURL"
|
||||
name="openID_callbackURL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDCallbackURL(e.target.value);
|
||||
cleanValidation("openID_callbackURL");
|
||||
}}
|
||||
label="Callback URL"
|
||||
value={openIDCallbackURL}
|
||||
placeholder="https://your-console-endpoint:9443/oauth_callback"
|
||||
error={validationErrors["openID_callbackURL"] || ""}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_claimName"
|
||||
name="openID_claimName"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDClaimName(e.target.value);
|
||||
cleanValidation("openID_claimName");
|
||||
}}
|
||||
label="Claim Name"
|
||||
value={openIDClaimName}
|
||||
error={validationErrors["openID_claimName"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="openID_scopes"
|
||||
name="openID_scopes"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setOpenIDScopes(e.target.value);
|
||||
cleanValidation("openID_scopes");
|
||||
}}
|
||||
label="Scopes"
|
||||
value={openIDScopes}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
{idpSelection === "AD" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="AD_URL"
|
||||
name="AD_URL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADURL(e.target.value);
|
||||
cleanValidation("AD_URL");
|
||||
}}
|
||||
label="LDAP Server Address"
|
||||
value={ADURL}
|
||||
placeholder="ldap-server:636"
|
||||
error={validationErrors["AD_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
{idpSelection === "AD" && (
|
||||
<Fragment>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="AD_URL"
|
||||
name="AD_URL"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADURL(e.target.value);
|
||||
cleanValidation("AD_URL");
|
||||
}}
|
||||
label="LDAP Server Address"
|
||||
value={ADURL}
|
||||
placeholder="ldap-server:636"
|
||||
error={validationErrors["AD_URL"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_skipTLS"
|
||||
id="ad_skipTLS"
|
||||
name="ad_skipTLS"
|
||||
checked={ADSkipTLS}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADSkipTLS(checked);
|
||||
}}
|
||||
label={"Skip TLS Verification"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_serverInsecure"
|
||||
id="ad_serverInsecure"
|
||||
name="ad_serverInsecure"
|
||||
checked={ADServerInsecure}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADServerInsecure(checked);
|
||||
}}
|
||||
label={"Server Insecure"}
|
||||
/>
|
||||
</Grid>
|
||||
{ADServerInsecure ? (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
className={classes.error}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
Warning: All traffic with Active Directory will be
|
||||
unencrypted
|
||||
</Typography>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_skipTLS"
|
||||
id="ad_skipTLS"
|
||||
name="ad_skipTLS"
|
||||
checked={ADSkipTLS}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADSkipTLS(checked);
|
||||
}}
|
||||
label={"Skip TLS Verification"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_serverInsecure"
|
||||
id="ad_serverInsecure"
|
||||
name="ad_serverInsecure"
|
||||
checked={ADServerInsecure}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADServerInsecure(checked);
|
||||
}}
|
||||
label={"Server Insecure"}
|
||||
/>
|
||||
</Grid>
|
||||
{ADServerInsecure ? (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
className={classes.error}
|
||||
variant="caption"
|
||||
display="block"
|
||||
gutterBottom
|
||||
>
|
||||
Warning: All traffic with Active Directory will be
|
||||
unencrypted
|
||||
</Typography>
|
||||
<br />
|
||||
</Grid>
|
||||
) : null}
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_serverStartTLS"
|
||||
id="ad_serverStartTLS"
|
||||
name="ad_serverStartTLS"
|
||||
checked={ADServerStartTLS}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADServerStartTLS(checked);
|
||||
}}
|
||||
label={"Start TLS connection to AD/LDAP server"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_lookupBindDN"
|
||||
name="ad_lookupBindDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADLookupBindDN(e.target.value);
|
||||
cleanValidation("ad_lookupBindDN");
|
||||
}}
|
||||
label="Lookup Bind DN"
|
||||
value={ADLookupBindDN}
|
||||
placeholder="cn=admin,dc=min,dc=io"
|
||||
error={validationErrors["ad_lookupBindDN"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
type={showADLookupBindPassword ? "text" : "password"}
|
||||
id="ad_lookupBindPassword"
|
||||
name="ad_lookupBindPassword"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADLookupBindPassword(e.target.value);
|
||||
}}
|
||||
label="Lookup Bind Password"
|
||||
value={ADLookupBindPassword}
|
||||
placeholder="admin"
|
||||
overlayIcon={
|
||||
showADLookupBindPassword ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowADLookupBindPassword(!showADLookupBindPassword)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchBaseDN"
|
||||
name="ad_userDNSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADUserDNSearchBaseDN(e.target.value);
|
||||
}}
|
||||
label="User DN Search Base DN"
|
||||
value={ADUserDNSearchBaseDN}
|
||||
placeholder="dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchFilter"
|
||||
name="ad_userDNSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADUserDNSearchFilter(e.target.value);
|
||||
}}
|
||||
label="User DN Search Filter"
|
||||
value={ADUserDNSearchFilter}
|
||||
placeholder="(sAMAcountName=%s)"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupSearchBaseDN"
|
||||
name="ad_groupSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADGroupSearchBaseDN(e.target.value);
|
||||
}}
|
||||
label="Group Search Base DN"
|
||||
value={ADGroupSearchBaseDN}
|
||||
placeholder="ou=hwengg,dc=min,dc=io;ou=swengg,dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupSearchFilter"
|
||||
name="ad_groupSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADGroupSearchFilter(e.target.value);
|
||||
}}
|
||||
label="Group Search Filter"
|
||||
value={ADGroupSearchFilter}
|
||||
placeholder="(&(objectclass=groupOfNames)(member=%s))"
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
) : null}
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="ad_serverStartTLS"
|
||||
id="ad_serverStartTLS"
|
||||
name="ad_serverStartTLS"
|
||||
checked={ADServerStartTLS}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setADServerStartTLS(checked);
|
||||
}}
|
||||
label={"Start TLS connection to AD/LDAP server"}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_lookupBindDN"
|
||||
name="ad_lookupBindDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADLookupBindDN(e.target.value);
|
||||
cleanValidation("ad_lookupBindDN");
|
||||
}}
|
||||
label="Lookup Bind DN"
|
||||
value={ADLookupBindDN}
|
||||
placeholder="cn=admin,dc=min,dc=io"
|
||||
error={validationErrors["ad_lookupBindDN"] || ""}
|
||||
required
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
type={showADLookupBindPassword ? "text" : "password"}
|
||||
id="ad_lookupBindPassword"
|
||||
name="ad_lookupBindPassword"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADLookupBindPassword(e.target.value);
|
||||
}}
|
||||
label="Lookup Bind Password"
|
||||
value={ADLookupBindPassword}
|
||||
placeholder="admin"
|
||||
overlayIcon={
|
||||
showADLookupBindPassword ? (
|
||||
<VisibilityOffIcon />
|
||||
) : (
|
||||
<RemoveRedEyeIcon />
|
||||
)
|
||||
}
|
||||
overlayAction={() =>
|
||||
setShowADLookupBindPassword(!showADLookupBindPassword)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchBaseDN"
|
||||
name="ad_userDNSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADUserDNSearchBaseDN(e.target.value);
|
||||
}}
|
||||
label="User DN Search Base DN"
|
||||
value={ADUserDNSearchBaseDN}
|
||||
placeholder="dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_userDNSearchFilter"
|
||||
name="ad_userDNSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADUserDNSearchFilter(e.target.value);
|
||||
}}
|
||||
label="User DN Search Filter"
|
||||
value={ADUserDNSearchFilter}
|
||||
placeholder="(sAMAcountName=%s)"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupSearchBaseDN"
|
||||
name="ad_groupSearchBaseDN"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADGroupSearchBaseDN(e.target.value);
|
||||
}}
|
||||
label="Group Search Base DN"
|
||||
value={ADGroupSearchBaseDN}
|
||||
placeholder="ou=hwengg,dc=min,dc=io;ou=swengg,dc=min,dc=io"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<InputBoxWrapper
|
||||
id="ad_groupSearchFilter"
|
||||
name="ad_groupSearchFilter"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setADGroupSearchFilter(e.target.value);
|
||||
}}
|
||||
label="Group Search Filter"
|
||||
value={ADGroupSearchFilter}
|
||||
placeholder="(&(objectclass=groupOfNames)(member=%s))"
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={!isFormValid || isSending}
|
||||
onClick={() => setDialogOpen(true)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Paper>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={!isFormValid || isSending}
|
||||
onClick={() => setDialogOpen(true)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
</React.Fragment>
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
tenantDetailsStyles,
|
||||
wizardCommon,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import React, { Fragment, useCallback, useEffect, useState } from "react";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
@@ -44,6 +43,7 @@ import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog";
|
||||
import { AddIcon, ConfirmModalIcon } from "../../../../icons";
|
||||
import Loader from "../../Common/Loader/Loader";
|
||||
import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate";
|
||||
import SectionTitle from "../../Common/SectionTitle";
|
||||
|
||||
interface ITenantSecurity {
|
||||
classes: any;
|
||||
@@ -78,12 +78,6 @@ const styles = (theme: Theme) =>
|
||||
flexFlow: "column",
|
||||
},
|
||||
},
|
||||
certInputRow: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
marginBottom: 10,
|
||||
},
|
||||
caCertsRow: {
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
display: "flex",
|
||||
@@ -341,212 +335,209 @@ const TenantSecurity = ({
|
||||
}
|
||||
/>
|
||||
{loadingTenant ? (
|
||||
<Paper className={classes.paperContainer}>
|
||||
<div className={classes.loaderAlign}>
|
||||
<Loader />
|
||||
</div>
|
||||
</Paper>
|
||||
<div className={classes.loaderAlign}>
|
||||
<Loader />
|
||||
</div>
|
||||
) : (
|
||||
<Fragment>
|
||||
<h1 className={classes.sectionTitle}>Security</h1>
|
||||
<Paper className={classes.paperContainer}>
|
||||
<Grid item xs={12} className={classes.title}>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="enableAutoCert"
|
||||
id="enableAutoCert"
|
||||
name="enableAutoCert"
|
||||
checked={enableAutoCert}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setEnableAutoCert(checked);
|
||||
}}
|
||||
label={"TLS"}
|
||||
description={
|
||||
"The internode certificates will be generated and managed by MinIO Operator"
|
||||
}
|
||||
/>
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12}>
|
||||
<h1 className={classes.sectionTitle}>Security</h1>
|
||||
<hr className={classes.hrClass} />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="enableAutoCert"
|
||||
id="enableAutoCert"
|
||||
name="enableAutoCert"
|
||||
checked={enableAutoCert}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setEnableAutoCert(checked);
|
||||
}}
|
||||
label={"TLS"}
|
||||
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;
|
||||
setEnableCustomCerts(checked);
|
||||
}}
|
||||
label={"Custom Certificates"}
|
||||
description={"Certificates used to terminated TLS at MinIO"}
|
||||
/>
|
||||
</Grid>
|
||||
|
||||
{enableCustomCerts && (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>MinIO Certificates</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.formFieldRow}>
|
||||
<FormSwitchWrapper
|
||||
value="enableCustomCerts"
|
||||
id="enableCustomCerts"
|
||||
name="enableCustomCerts"
|
||||
checked={enableCustomCerts}
|
||||
onChange={(e) => {
|
||||
const targetD = e.target;
|
||||
const checked = targetD.checked;
|
||||
setEnableCustomCerts(checked);
|
||||
}}
|
||||
label={"Custom Certificates"}
|
||||
/>
|
||||
<Grid item xs={12}>
|
||||
{minioTLSCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{enableCustomCerts && (
|
||||
<Fragment>
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
<h4>MinIO Certificates</h4>
|
||||
</Grid>
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
{minioTLSCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
{minioCertificates.map((keyPair) => (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
key={keyPair.id}
|
||||
className={classes.certInputRow}
|
||||
>
|
||||
<Grid item xs={9} className={classes.fileItem}>
|
||||
<Grid item xs={6}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minio",
|
||||
keyPair.id,
|
||||
"cert",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".cer,.crt,.cert,.pem"
|
||||
id="tlsCert"
|
||||
name="tlsCert"
|
||||
label="Cert"
|
||||
value={keyPair.cert}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={6} className={classes.spacerLeft}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minio",
|
||||
keyPair.id,
|
||||
"key",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".key,.pem"
|
||||
id="tlsKey"
|
||||
name="tlsKey"
|
||||
label="Key"
|
||||
value={keyPair.key}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item md={2} xs={1}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => deleteKeyPair("minio", keyPair.id)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
endIcon={<AddIcon />}
|
||||
onClick={() => addKeyPair("minio")}
|
||||
<Grid item xs={12}>
|
||||
{minioCertificates.map((keyPair) => (
|
||||
<Grid
|
||||
container
|
||||
key={keyPair.id}
|
||||
alignItems={"center"}
|
||||
style={{ borderBottom: "1px solid #eaeaea" }}
|
||||
>
|
||||
Add Certificate
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
<h4>MinIO CA Certificates</h4>
|
||||
</Grid>
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
{minioTLSCaCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
<Grid item xs={5}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minio",
|
||||
keyPair.id,
|
||||
"cert",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".cer,.crt,.cert,.pem"
|
||||
id="tlsCert"
|
||||
name="tlsCert"
|
||||
label="Cert"
|
||||
value={keyPair.cert}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
{minioCaCertificates.map((keyPair: KeyPair) => (
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
className={classes.caCertsRow}
|
||||
key={keyPair.id}
|
||||
>
|
||||
<Grid item xs={9} className={classes.fileItem}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minioCAs",
|
||||
keyPair.id,
|
||||
"cert",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".cer,.crt,.cert,.pem"
|
||||
id="tlsCert"
|
||||
name="tlsCert"
|
||||
label="Cert"
|
||||
value={keyPair.cert}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={1}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => deleteKeyPair("minioCAs", keyPair.id)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Grid container item xs={12} className={classes.formFieldRow}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
endIcon={<AddIcon />}
|
||||
onClick={() => addKeyPair("minioCAs")}
|
||||
>
|
||||
Add CA Certificate
|
||||
</Button>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
<Grid item xs={5}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minio",
|
||||
keyPair.id,
|
||||
"key",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".key,.pem"
|
||||
id="tlsKey"
|
||||
name="tlsKey"
|
||||
label="Key"
|
||||
value={keyPair.key}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => deleteKeyPair("minio", keyPair.id)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Grid item xs={12} textAlign={"right"}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
endIcon={<AddIcon />}
|
||||
onClick={() => addKeyPair("minio")}
|
||||
>
|
||||
Add Certificate
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={dialogOpen || isSending}
|
||||
onClick={() => setDialogOpen(true)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Paper>
|
||||
</Fragment>
|
||||
<Grid item xs={12}>
|
||||
<SectionTitle>MinIO CA Certificates</SectionTitle>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{minioTLSCaCertificateSecrets.map(
|
||||
(certificateInfo: ICertificateInfo) => (
|
||||
<TLSCertificate
|
||||
certificateInfo={certificateInfo}
|
||||
onDelete={() => removeCertificate(certificateInfo)}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12}>
|
||||
{minioCaCertificates.map((keyPair: KeyPair) => (
|
||||
<Grid
|
||||
container
|
||||
key={keyPair.id}
|
||||
style={{ borderBottom: "1px solid #eaeaea" }}
|
||||
alignItems={"center"}
|
||||
justifyContent={"space-between"}
|
||||
>
|
||||
<Grid item xs={5} className={classes.fileItem}>
|
||||
<FileSelector
|
||||
onChange={(encodedValue, fileName) =>
|
||||
addFileToKeyPair(
|
||||
"minioCAs",
|
||||
keyPair.id,
|
||||
"cert",
|
||||
fileName,
|
||||
encodedValue
|
||||
)
|
||||
}
|
||||
accept=".cer,.crt,.cert,.pem"
|
||||
id="tlsCert"
|
||||
name="tlsCert"
|
||||
label="Cert"
|
||||
value={keyPair.cert}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={2}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={() => deleteKeyPair("minioCAs", keyPair.id)}
|
||||
>
|
||||
Remove
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
<Grid item xs={12} textAlign={"right"}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
endIcon={<AddIcon />}
|
||||
onClick={() => addKeyPair("minioCAs")}
|
||||
>
|
||||
Add CA Certificate
|
||||
</Button>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
|
||||
<Grid item xs={12} textAlign={"right"}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={dialogOpen || isSending}
|
||||
onClick={() => setDialogOpen(true)}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -24,17 +24,15 @@ import {
|
||||
containerForHeader,
|
||||
tenantDetailsStyles,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import { Box, Grid, Stack } from "@mui/material";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import { Box, Grid } from "@mui/material";
|
||||
import { ITenant } from "../ListTenants/types";
|
||||
import UpdateTenantModal from "./UpdateTenantModal";
|
||||
import { AppState } from "../../../../store";
|
||||
import AButton from "../../Common/AButton/AButton";
|
||||
import { styled } from "@mui/styles";
|
||||
import SummaryUsageBar from "../../Common/UsageBarWrapper/SummaryUsageBar";
|
||||
import LabelValuePair from "../../Common/UsageBarWrapper/LabelValuePair";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import StackRow from "../../Common/UsageBarWrapper/StackRow";
|
||||
import SectionTitle from "../../Common/SectionTitle";
|
||||
|
||||
interface ITenantsSummary {
|
||||
classes: any;
|
||||
@@ -114,10 +112,6 @@ const styles = (theme: Theme) =>
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const StackItem = styled(Paper)(({ theme }) => ({
|
||||
border: 0,
|
||||
}));
|
||||
|
||||
const healthStatusToClass = (health_status: string = "red", classes: any) => {
|
||||
return health_status === "red"
|
||||
? classes.redState
|
||||
@@ -226,15 +220,7 @@ const TenantSummary = ({
|
||||
/>
|
||||
)}
|
||||
|
||||
<Stack
|
||||
direction={{ xs: "column-reverse", sm: "row" }}
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<StackItem>
|
||||
<h3>Details</h3>
|
||||
</StackItem>
|
||||
<StackItem></StackItem>
|
||||
</Stack>
|
||||
<SectionTitle separator={false}>Details</SectionTitle>
|
||||
|
||||
<StorageSummary tenant={tenant} classes={classes} />
|
||||
|
||||
@@ -361,64 +347,49 @@ const TenantSummary = ({
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Stack>
|
||||
<StackRow
|
||||
sx={{
|
||||
borderBottom: "1px solid #eaeaea",
|
||||
margin: 0,
|
||||
}}
|
||||
>
|
||||
<h3
|
||||
style={{
|
||||
marginBottom: 10,
|
||||
}}
|
||||
>
|
||||
Features
|
||||
</h3>
|
||||
</StackRow>
|
||||
<Box sx={{ ...featureRowStyle }}>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label="Logs:"
|
||||
value={getToggle(logEnabled, "tenant-log")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<SectionTitle>Features</SectionTitle>
|
||||
<Box sx={{ ...featureRowStyle }}>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label="Logs:"
|
||||
value={getToggle(logEnabled, "tenant-log")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"AD/LDAP:"}
|
||||
value={getToggle(adEnabled, "tenant-sts")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"Encryption:"}
|
||||
value={getToggle(encryptionEnabled, "tenant-enc")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ ...featureRowStyle }}>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label="MinIO TLS:"
|
||||
value={getToggle(minioTLS, "tenant-tls")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"AD/LDAP:"}
|
||||
value={getToggle(adEnabled, "tenant-sts")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"Encryption:"}
|
||||
value={getToggle(encryptionEnabled, "tenant-enc")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
</Box>
|
||||
<Box sx={{ ...featureRowStyle }}>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label="MinIO TLS:"
|
||||
value={getToggle(minioTLS, "tenant-tls")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"Monitoring:"}
|
||||
value={getToggle(monitoringEnabled, "tenant-monitor")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"OpenID:"}
|
||||
value={getToggle(oidcEnabled, "tenant-oidc")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
</Box>
|
||||
</Stack>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"Monitoring:"}
|
||||
value={getToggle(monitoringEnabled, "tenant-monitor")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
<LabelValuePair
|
||||
orientation="row"
|
||||
label={"OpenID:"}
|
||||
value={getToggle(oidcEnabled, "tenant-oidc")}
|
||||
{...featureItemStyleProps}
|
||||
/>
|
||||
</Box>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -131,59 +131,61 @@ const TenantVolumes = ({
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
<h1 className={classes.sectionTitle}>Volumes</h1>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Volumes (PVCs)"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setFilter(e.target.value);
|
||||
}}
|
||||
variant="standard"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.tableBlock}>
|
||||
<TableWrapper
|
||||
itemActions={[
|
||||
{ type: "view", onClick: PVCViewAction },
|
||||
{ type: "delete", onClick: confirmDeletePVC },
|
||||
]}
|
||||
columns={[
|
||||
{
|
||||
label: "Name",
|
||||
elementKey: "name",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
elementKey: "status",
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
label: "Capacity",
|
||||
elementKey: "capacity",
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
label: "Storage Class",
|
||||
elementKey: "storageClass",
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="PVCs"
|
||||
idField="name"
|
||||
customPaperHeight={classes.tableWrapper}
|
||||
/>
|
||||
<Grid container spacing={1}>
|
||||
<h1 className={classes.sectionTitle}>Volumes</h1>
|
||||
<Grid item xs={12}>
|
||||
<TextField
|
||||
placeholder="Search Volumes (PVCs)"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
onChange={(e) => {
|
||||
setFilter(e.target.value);
|
||||
}}
|
||||
variant="standard"
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.tableBlock}>
|
||||
<TableWrapper
|
||||
itemActions={[
|
||||
{ type: "view", onClick: PVCViewAction },
|
||||
{ type: "delete", onClick: confirmDeletePVC },
|
||||
]}
|
||||
columns={[
|
||||
{
|
||||
label: "Name",
|
||||
elementKey: "name",
|
||||
},
|
||||
{
|
||||
label: "Status",
|
||||
elementKey: "status",
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
label: "Capacity",
|
||||
elementKey: "capacity",
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
label: "Storage Class",
|
||||
elementKey: "storageClass",
|
||||
},
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="PVCs"
|
||||
idField="name"
|
||||
customPaperHeight={classes.tableWrapper}
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user