Added Edit minio image functionality (#474)
Co-authored-by: Benjamin Perez <benjamin@bexsoft.net> Co-authored-by: Cesar N <ces.nietor@gmail.com> Co-authored-by: Daniel Valdivia <hola@danielvaldivia.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import { IIcon, selected, unSelected } from "./common";
|
||||
|
||||
const PencilIcon = ({ active = false }: IIcon) => {
|
||||
const DescriptionIcon = ({ active = false }: IIcon) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -18,4 +18,4 @@ const PencilIcon = ({ active = false }: IIcon) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default PencilIcon;
|
||||
export default DescriptionIcon;
|
||||
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
modalBasic,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { Button } from "@material-ui/core";
|
||||
import { Button, IconButton } from "@material-ui/core";
|
||||
import Tabs from "@material-ui/core/Tabs";
|
||||
import Tab from "@material-ui/core/Tab";
|
||||
import { CreateIcon } from "../../../../icons";
|
||||
@@ -40,6 +40,9 @@ import Watch from "./Watch/Watch";
|
||||
import Heal from "./Heal/Heal";
|
||||
import PageHeader from "../../Common/PageHeader/PageHeader";
|
||||
import UsageBarWrapper from "../../Common/UsageBarWrapper/UsageBarWrapper";
|
||||
import UpdateTenantModal from "./UpdateTenantModal";
|
||||
import EditIcon from "@material-ui/icons/Edit";
|
||||
import PencilIcon from "../../Common/TableWrapper/TableActionIcons/PencilIcon";
|
||||
|
||||
interface ITenantDetailsProps {
|
||||
classes: any;
|
||||
@@ -100,6 +103,18 @@ const styles = (theme: Theme) =>
|
||||
actionsTray: {
|
||||
textAlign: "right",
|
||||
},
|
||||
updateButton: {
|
||||
backgroundColor: "transparent",
|
||||
border: 0,
|
||||
padding: "0 6px",
|
||||
cursor: "pointer",
|
||||
"&:focus, &:active": {
|
||||
outline: "none",
|
||||
},
|
||||
"& svg": {
|
||||
height: 12,
|
||||
},
|
||||
},
|
||||
...modalBasic,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
@@ -119,6 +134,7 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
const [loadingUsage, setLoadingUsage] = useState<boolean>(true);
|
||||
const [usageError, setUsageError] = useState<string>("");
|
||||
const [usage, setUsage] = useState<number>(0);
|
||||
const [updateMinioVersion, setUpdateMinioVersion] = useState<boolean>(false);
|
||||
|
||||
const tenantName = match.params["tenantName"];
|
||||
const tenantNamespace = match.params["tenantNamespace"];
|
||||
@@ -228,6 +244,16 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
closeModalAndRefresh={closeReplicationAndRefresh}
|
||||
/>
|
||||
)}
|
||||
{updateMinioVersion && (
|
||||
<UpdateTenantModal
|
||||
open={updateMinioVersion}
|
||||
closeModalAndRefresh={() => {
|
||||
setUpdateMinioVersion(false);
|
||||
}}
|
||||
idTenant={tenantName}
|
||||
namespace={tenantNamespace}
|
||||
/>
|
||||
)}
|
||||
<PageHeader label={`Tenant > ${match.params["tenantName"]}`} />
|
||||
<Grid item xs={12} className={classes.container} />
|
||||
<Grid container>
|
||||
@@ -245,7 +271,17 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
|
||||
<div>Capacity:</div>
|
||||
<div>{niceBytes(capacity.toString(10))}</div>
|
||||
<div>Minio:</div>
|
||||
<div>{tenant ? tenant.image : ""}</div>
|
||||
<div>
|
||||
{tenant ? tenant.image : ""}{" "}
|
||||
<button
|
||||
className={classes.updateButton}
|
||||
onClick={() => {
|
||||
setUpdateMinioVersion(true);
|
||||
}}
|
||||
>
|
||||
<PencilIcon active={false} />
|
||||
</button>
|
||||
</div>
|
||||
<div>Clusters:</div>
|
||||
<div>{poolCount}</div>
|
||||
<div>Console:</div>
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
import React, { useState, Fragment, useEffect } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
|
||||
import { Button, Grid } from "@material-ui/core";
|
||||
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
|
||||
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
|
||||
import api from "../../../../common/api";
|
||||
import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
|
||||
|
||||
interface IUpdateTenantModal {
|
||||
open: boolean;
|
||||
closeModalAndRefresh: (update: boolean) => any;
|
||||
namespace: string;
|
||||
idTenant: string;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
errorBlock: {
|
||||
color: "red",
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
const UpdateTenantModal = ({
|
||||
open,
|
||||
closeModalAndRefresh,
|
||||
namespace,
|
||||
idTenant,
|
||||
classes,
|
||||
}: IUpdateTenantModal) => {
|
||||
const [isLoading, setIsLoading] = useState<boolean>(true);
|
||||
const [isSending, setIsSending] = useState<boolean>(false);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [minioImage, setMinioImage] = useState<string>("");
|
||||
const [consoleImage, setConsoleImage] = useState<string>("");
|
||||
const [imageRegistry, setImageRegistry] = useState<boolean>(false);
|
||||
const [imageRegistryEndpoint, setImageRegistryEndpoint] = useState<string>(
|
||||
""
|
||||
);
|
||||
const [imageRegistryUsername, setImageRegistryUsername] = useState<string>(
|
||||
""
|
||||
);
|
||||
const [imageRegistryPassword, setImageRegistryPassword] = useState<string>(
|
||||
""
|
||||
);
|
||||
const [validMinioImage, setValidMinioImage] = useState<boolean>(true);
|
||||
const [validConsoleImage, setValidConsoleImage] = useState<boolean>(true);
|
||||
|
||||
useEffect(() => {
|
||||
validateImage("minioImage");
|
||||
}, [minioImage]);
|
||||
|
||||
useEffect(() => {
|
||||
validateImage("consoleImage");
|
||||
}, [consoleImage]);
|
||||
|
||||
const closeAction = () => {
|
||||
closeModalAndRefresh(false);
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
setMinioImage("");
|
||||
setConsoleImage("");
|
||||
setImageRegistry(false);
|
||||
setImageRegistryEndpoint("");
|
||||
setImageRegistryUsername("");
|
||||
setImageRegistryPassword("");
|
||||
};
|
||||
|
||||
const updateMinIOImage = () => {
|
||||
setIsSending(true);
|
||||
|
||||
let payload = {
|
||||
image: minioImage,
|
||||
console_image: consoleImage,
|
||||
enable_prometheus: true,
|
||||
};
|
||||
|
||||
if (imageRegistry) {
|
||||
const registry: any = {
|
||||
image_registry: {
|
||||
registry: imageRegistryEndpoint,
|
||||
username: imageRegistryUsername,
|
||||
password: imageRegistryPassword,
|
||||
},
|
||||
};
|
||||
payload = {
|
||||
...payload,
|
||||
...registry,
|
||||
};
|
||||
}
|
||||
|
||||
api
|
||||
.invoke(
|
||||
"PUT",
|
||||
`/api/v1/namespaces/${namespace}/tenants/${idTenant}`,
|
||||
payload
|
||||
)
|
||||
.then((res) => {
|
||||
setIsSending(false);
|
||||
closeModalAndRefresh(true);
|
||||
})
|
||||
.catch((error) => {
|
||||
setError(error);
|
||||
setIsSending(false);
|
||||
});
|
||||
};
|
||||
|
||||
const validateImage = (fieldToCheck: string) => {
|
||||
const pattern = new RegExp("^$|^((.*?)/(.*?):(.+))$");
|
||||
|
||||
switch (fieldToCheck) {
|
||||
case "consoleImage":
|
||||
setValidConsoleImage(pattern.test(consoleImage));
|
||||
break;
|
||||
case "minioImage":
|
||||
setValidMinioImage(pattern.test(minioImage));
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
title={"Update MinIO Version"}
|
||||
modalOpen={open}
|
||||
onClose={closeAction}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
{error !== "" && <span className={classes.errorBlock}>{error}</span>}
|
||||
<span>
|
||||
Please enter the MinIO image from dockerhub to use. If blank, then
|
||||
latest build will be used.
|
||||
</span>
|
||||
<br />
|
||||
<br />
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={minioImage}
|
||||
label={"MinIO's Image"}
|
||||
id={"minioImage"}
|
||||
name={"minioImage"}
|
||||
placeholder={"E.g. minio/minio:RELEASE.2020-05-08T02-40-49Z"}
|
||||
onChange={(e) => {
|
||||
setMinioImage(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={consoleImage}
|
||||
label={"Console's Image"}
|
||||
id={"consoleImage"}
|
||||
name={"consoleImage"}
|
||||
placeholder={"E.g. minio/console:v0.3.13"}
|
||||
onChange={(e) => {
|
||||
setConsoleImage(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="imageRegistry"
|
||||
id="setImageRegistry"
|
||||
name="setImageRegistry"
|
||||
checked={imageRegistry}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setImageRegistry(!imageRegistry);
|
||||
}}
|
||||
label={"Set Custom Image Registry"}
|
||||
indicatorLabels={["Yes", "No"]}
|
||||
/>
|
||||
</Grid>
|
||||
{imageRegistry && (
|
||||
<Fragment>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={imageRegistryEndpoint}
|
||||
label={"Endpoint"}
|
||||
id={"imageRegistry"}
|
||||
name={"imageRegistry"}
|
||||
placeholder={"E.g. https://index.docker.io/v1/"}
|
||||
onChange={(e) => {
|
||||
setImageRegistryEndpoint(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={imageRegistryUsername}
|
||||
label={"Username"}
|
||||
id={"imageRegistryUsername"}
|
||||
name={"imageRegistryUsername"}
|
||||
placeholder={"Enter image registry username"}
|
||||
onChange={(e) => {
|
||||
setImageRegistryUsername(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<InputBoxWrapper
|
||||
value={imageRegistryPassword}
|
||||
label={"Password"}
|
||||
id={"imageRegistryPassword"}
|
||||
name={"imageRegistryPassword"}
|
||||
placeholder={"Enter image registry password"}
|
||||
onChange={(e) => {
|
||||
setImageRegistryPassword(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={
|
||||
!validMinioImage ||
|
||||
!validConsoleImage ||
|
||||
(imageRegistry &&
|
||||
(imageRegistryEndpoint.trim() === "" ||
|
||||
imageRegistryUsername.trim() === "" ||
|
||||
imageRegistryPassword.trim() === "")) ||
|
||||
isSending
|
||||
}
|
||||
onClick={updateMinIOImage}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(UpdateTenantModal);
|
||||
Reference in New Issue
Block a user