diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/AddReplicationModal.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/AddReplicationModal.tsx
index 98ffe358f..1d19642e9 100644
--- a/portal-ui/src/screens/Console/Buckets/ViewBucket/AddReplicationModal.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/AddReplicationModal.tsx
@@ -25,11 +25,7 @@ import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBo
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
import { Button, LinearProgress } from "@material-ui/core";
import api from "../../../../common/api";
-import {
- IRemoteBucket,
- IRemoteBucketsResponse,
-} from "../../RemoteBuckets/types";
-import RemoteBucketsList from "../../RemoteBuckets/RemoteBuckets";
+import { IRemoteBucket } from "../types";
interface IReplicationModal {
open: boolean;
@@ -64,42 +60,61 @@ const AddReplicationModal = ({
bucketName,
}: IReplicationModal) => {
const [addError, setAddError] = useState("");
- const [loadingForm, setLoadingForm] = useState(true);
const [addLoading, setAddLoading] = useState(false);
- const [remoteURL, setRemoteURL] = useState("");
- const [source, setSource] = useState("");
- const [target, setTarget] = useState("");
- const [ARN, setARN] = useState("");
- const [arnValues, setARNValues] = useState([]);
-
- useEffect(() => {
- if (addLoading) {
- addRecord();
- }
- }, [addLoading]);
-
- useEffect(() => {
- if (loadingForm) {
- getARNValues();
- }
- });
+ const [accessKey, setAccessKey] = useState("");
+ const [secretKey, setSecretKey] = useState("");
+ const [targetURL, setTargetURL] = useState("");
+ const [targetBucket, setTargetBucket] = useState("");
+ const [region, setRegion] = useState("");
const addRecord = () => {
- const replicationInfo = {
- destination_bucket: target,
- arn: ARN,
+ const remoteBucketInfo = {
+ accessKey: accessKey,
+ secretKey: secretKey,
+ sourceBucket: bucketName,
+ targetURL: targetURL,
+ targetBucket: targetBucket,
+ region: region,
};
api
- .invoke(
- "POST",
- `/api/v1/buckets/${bucketName}/replication`,
- replicationInfo
- )
- .then((res) => {
- setAddLoading(false);
- setAddError("");
- closeModalAndRefresh();
+ .invoke("POST", "/api/v1/remote-buckets", remoteBucketInfo)
+ .then(() => {
+ api
+ .invoke("GET", "/api/v1/remote-buckets")
+ .then((res: any) => {
+ const remoteBuckets = get(res, "buckets", []);
+ const remoteBucket = remoteBuckets.find(
+ (itemRemote: IRemoteBucket) => {
+ return itemRemote.sourceBucket === bucketName;
+ }
+ );
+ if (remoteBucket && remoteBucket.remoteARN) {
+ const remoteARN = remoteBucket.remoteARN;
+ const replicationInfo = {
+ destination_bucket: targetBucket,
+ arn: remoteARN,
+ };
+ api
+ .invoke(
+ "POST",
+ `/api/v1/buckets/${bucketName}/replication`,
+ replicationInfo
+ )
+ .then(() => {
+ setAddLoading(false);
+ setAddError("");
+ closeModalAndRefresh();
+ })
+ .catch((err) => {
+ setAddLoading(false);
+ setAddError(err);
+ });
+ }
+ })
+ .catch((err) => {
+ setAddError(err);
+ });
})
.catch((err) => {
setAddLoading(false);
@@ -107,23 +122,6 @@ const AddReplicationModal = ({
});
};
- const getARNValues = () => {
- api
- .invoke("GET", "/api/v1/remote-buckets")
- .then((res: any) => {
- const remoteBuckets = get(res, "buckets", []);
-
- const remoteARNS = remoteBuckets.map((itemRemote: IRemoteBucket) => {
- return { label: itemRemote.remoteARN, value: itemRemote.remoteARN };
- });
- setLoadingForm(false);
- setARNValues(remoteARNS);
- })
- .catch((err) => {
- setLoadingForm(false);
- });
- };
-
return (
) => {
e.preventDefault();
setAddLoading(true);
+ addRecord();
}}
>
- {loadingForm && (
-
+
+
+ {addError !== "" && (
+
+
+ {addError}
+
+
+ )}
+
+
+ ) => {
+ setAccessKey(e.target.value);
+ }}
+ label="Access Key"
+ value={accessKey}
+ />
+
+
+ ) => {
+ setSecretKey(e.target.value);
+ }}
+ label="Secret Key"
+ value={secretKey}
+ />
+
+
+ ) => {
+ setTargetURL(e.target.value);
+ }}
+ placeholder="https://play.min.io:9000"
+ label="Target URL"
+ value={targetURL}
+ />
+
+
+ ) => {
+ setTargetBucket(e.target.value);
+ }}
+ label="Target Bucket"
+ value={targetBucket}
+ />
+
+
+ ) => {
+ setRegion(e.target.value);
+ }}
+ label="Region"
+ value={region}
+ />
+
+
+
+
+
+ {addLoading && (
-
- )}
- {!loadingForm && (
-
-
- {addError !== "" && (
-
-
- {addError}
-
-
- )}
-
-
- ) => {
- setTarget(e.target.value);
- }}
- label="Destination Bucket"
- value={target}
- />
-
-
- ) => {
- setARN(e.target.value as string);
- }}
- id="arn"
- name="arn"
- label={"ARN"}
- value={ARN}
- options={arnValues}
- />
-
-
-
-
-
- {addLoading && (
-
-
-
- )}
-
- )}
+ )}
+
);
diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx
index ea565e435..483ac3605 100644
--- a/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx
@@ -515,51 +515,53 @@ class ViewBucket extends React.Component {
-
- , newValue: number) => {
- this.setState({ curTab: newValue });
- }}
- indicatorColor="primary"
- textColor="primary"
- aria-label="cluster-tabs"
- >
-
-
-
-
-
- {curTab === 0 && (
- }
- size="medium"
- onClick={() => {
- this.setState({
- addScreenOpen: true,
- });
+
+
+ , newValue: number) => {
+ this.setState({ curTab: newValue });
}}
+ indicatorColor="primary"
+ textColor="primary"
+ aria-label="cluster-tabs"
>
- Subscribe to Event
-
- )}
- {curTab === 1 && (
- }
- size="medium"
- onClick={() => {
- this.setState({
- openSetReplication: true,
- });
- }}
- >
- Add Replication Rule
-
- )}
+
+
+
+
+
+ {curTab === 0 && (
+ }
+ size="medium"
+ onClick={() => {
+ this.setState({
+ addScreenOpen: true,
+ });
+ }}
+ >
+ Subscribe to Event
+
+ )}
+ {curTab === 1 && (
+ }
+ size="medium"
+ onClick={() => {
+ this.setState({
+ openSetReplication: true,
+ });
+ }}
+ >
+ Add Replication Rule
+
+ )}
+
diff --git a/portal-ui/src/screens/Console/Buckets/types.tsx b/portal-ui/src/screens/Console/Buckets/types.tsx
index ea1a2631f..1bb64fee1 100644
--- a/portal-ui/src/screens/Console/Buckets/types.tsx
+++ b/portal-ui/src/screens/Console/Buckets/types.tsx
@@ -79,3 +79,15 @@ export interface MakeBucketRequest {
versioning: boolean;
quota?: QuotaRequest;
}
+
+export interface IRemoteBucket {
+ name: string;
+ accessKey: string;
+ secretKey: string;
+ sourceBucket: string;
+ targetURL: string;
+ targetBucket: string;
+ remoteARN: string;
+ status: string;
+ service: string;
+}
diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx
index 1a4812a6a..3f9135d1c 100644
--- a/portal-ui/src/screens/Console/Console.tsx
+++ b/portal-ui/src/screens/Console/Console.tsx
@@ -67,7 +67,6 @@ import { ISessionResponse } from "./types";
import { saveSessionResponse } from "./actions";
import TenantDetails from "./Tenants/TenantDetails/TenantDetails";
import { clearSession } from "../../common/utils";
-import RemoteBuckets from "./RemoteBuckets/RemoteBuckets";
import ObjectBrowser from "./ObjectBrowser/ObjectBrowser";
import ListObjects from "./Buckets/ListBuckets/Objects/ListObjects/ListObjects";
@@ -279,10 +278,6 @@ const Console = ({
component: Policies,
path: "/policies",
},
- {
- component: RemoteBuckets,
- path: "/remote-buckets",
- },
{
component: Trace,
path: "/trace",
diff --git a/portal-ui/src/screens/Console/Menu/Menu.tsx b/portal-ui/src/screens/Console/Menu/Menu.tsx
index 2b4c20e20..bc8840860 100644
--- a/portal-ui/src/screens/Console/Menu/Menu.tsx
+++ b/portal-ui/src/screens/Console/Menu/Menu.tsx
@@ -21,7 +21,6 @@ import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import WebAssetIcon from "@material-ui/icons/WebAsset";
import HealingIcon from "@material-ui/icons/Healing";
-import CloudUploadIcon from "@material-ui/icons/CloudUpload";
import DescriptionIcon from "@material-ui/icons/Description";
import FileCopyIcon from "@material-ui/icons/FileCopy";
import Collapse from "@material-ui/core/Collapse";
@@ -247,14 +246,6 @@ const Menu = ({ userLoggedIn, classes, pages }: IMenuProps) => {
name: "IAM Policies",
icon: ,
},
- {
- group: "Admin",
- type: "item",
- component: NavLink,
- to: "/remote-buckets",
- name: "Remote Buckets",
- icon: ,
- },
{
group: "Tools",
type: "item",
diff --git a/portal-ui/src/screens/Console/RemoteBuckets/AddRemoteBucket.tsx b/portal-ui/src/screens/Console/RemoteBuckets/AddRemoteBucket.tsx
deleted file mode 100644
index 43301870d..000000000
--- a/portal-ui/src/screens/Console/RemoteBuckets/AddRemoteBucket.tsx
+++ /dev/null
@@ -1,209 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2020 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 .
-
-import React, { useState, useEffect } from "react";
-import Grid from "@material-ui/core/Grid";
-import Typography from "@material-ui/core/Typography";
-import { Button, LinearProgress } from "@material-ui/core";
-import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
-import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
-import api from "../../../common/api";
-import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
-import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
-import SelectWrapper from "../Common/FormComponents/SelectWrapper/SelectWrapper";
-
-const styles = (theme: Theme) =>
- createStyles({
- errorBlock: {
- color: "red",
- },
- buttonContainer: {
- textAlign: "right",
- },
- ...modalBasic,
- });
-
-interface IAddBucketProps {
- classes: any;
- open: boolean;
- closeModalAndRefresh: () => void;
-}
-
-const AddRemoteBucket = ({
- classes,
- open,
- closeModalAndRefresh,
-}: IAddBucketProps) => {
- const [addLoading, setAddLoading] = useState(false);
- const [addError, setAddError] = useState("");
- const [accessKey, setAccessKey] = useState("");
- const [secretKey, setSecretKey] = useState("");
- const [sourceBucket, setSourceBucket] = useState("");
- const [targetURL, setTargetURL] = useState("");
- const [targetBucket, setTargetBucket] = useState("");
- const [region, setRegion] = useState("");
-
- useEffect(() => {
- if (addLoading) {
- addRecord();
- }
- }, [addLoading]);
-
- const addRecord = () => {
- const remoteBucketInfo = {
- accessKey: accessKey,
- secretKey: secretKey,
- sourceBucket: sourceBucket,
- targetURL: targetURL,
- targetBucket: targetBucket,
- region: region,
- };
-
- api
- .invoke("POST", "/api/v1/remote-buckets", remoteBucketInfo)
- .then((res) => {
- setAddLoading(false);
- setAddError("");
- closeModalAndRefresh();
- })
- .catch((err) => {
- setAddLoading(false);
- setAddError(err);
- });
- };
-
- return (
- {
- setAddError("");
- closeModalAndRefresh();
- }}
- aria-labelledby="alert-dialog-title"
- aria-describedby="alert-dialog-description"
- >
-
-
- );
-};
-
-export default withStyles(styles)(AddRemoteBucket);
diff --git a/portal-ui/src/screens/Console/RemoteBuckets/DeleteRemoteBucket.tsx b/portal-ui/src/screens/Console/RemoteBuckets/DeleteRemoteBucket.tsx
deleted file mode 100644
index 1e97a50d0..000000000
--- a/portal-ui/src/screens/Console/RemoteBuckets/DeleteRemoteBucket.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2020 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 .
-
-import React, { useState, useEffect } from "react";
-import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
-import get from "lodash/get";
-import {
- Button,
- Dialog,
- DialogActions,
- DialogContent,
- DialogContentText,
- DialogTitle,
- LinearProgress,
-} from "@material-ui/core";
-import api from "../../../common/api";
-import Typography from "@material-ui/core/Typography";
-
-const styles = (theme: Theme) =>
- createStyles({
- errorBlock: {
- color: "red",
- },
- });
-
-interface IDeleteEventProps {
- classes: any;
- closeDeleteModalAndRefresh: (refresh: boolean) => void;
- deleteOpen: boolean;
- bucketName: any;
- sourceBucket: string;
-}
-
-interface IDeleteEventState {
- deleteLoading: boolean;
- deleteError: string;
-}
-
-const DeleteRemoteBucket = ({
- deleteOpen,
- closeDeleteModalAndRefresh,
- classes,
- bucketName,
- sourceBucket,
-}: IDeleteEventProps) => {
- const [deleteError, setDeleteError] = useState("");
- const [deleteLoading, setDeleteLoading] = useState(false);
-
- useEffect(() => {
- if (deleteLoading) {
- removeRecord();
- }
- }, [deleteLoading]);
-
- const removeRecord = () => {
- api
- .invoke("DELETE", `/api/v1/remote-buckets/${sourceBucket}/${bucketName}`)
- .then(() => {
- setDeleteLoading(false);
- setDeleteError("");
- closeDeleteModalAndRefresh(true);
- })
- .catch((err) => {
- setDeleteLoading(false);
- setDeleteError(err);
- });
- };
-
- return (
-
- );
-};
-
-export default withStyles(styles)(DeleteRemoteBucket);
diff --git a/portal-ui/src/screens/Console/RemoteBuckets/RemoteBuckets.tsx b/portal-ui/src/screens/Console/RemoteBuckets/RemoteBuckets.tsx
deleted file mode 100644
index f187844c9..000000000
--- a/portal-ui/src/screens/Console/RemoteBuckets/RemoteBuckets.tsx
+++ /dev/null
@@ -1,273 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2020 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 .
-
-import React, { useState, useEffect } from "react";
-import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
-import Grid from "@material-ui/core/Grid";
-import { Button } from "@material-ui/core";
-import Typography from "@material-ui/core/Typography";
-import TextField from "@material-ui/core/TextField";
-import InputAdornment from "@material-ui/core/InputAdornment";
-import SearchIcon from "@material-ui/icons/Search";
-import Moment from "react-moment";
-import api from "../../../common/api";
-import { Bucket } from "../Buckets/types";
-import TableWrapper from "../Common/TableWrapper/TableWrapper";
-import AddRemoteBucket from "./AddRemoteBucket";
-import { MinTablePaginationActions } from "../../../common/MinTablePaginationActions";
-import { CreateIcon } from "../../../icons";
-import { IRemoteBucket, IRemoteBucketsResponse } from "./types";
-import DeleteRemoteBucket from "./DeleteRemoteBucket";
-import {
- actionsTray,
- containerForHeader,
- searchField,
-} from "../Common/FormComponents/common/styleLibrary";
-import PageHeader from "../Common/PageHeader/PageHeader";
-
-const styles = (theme: Theme) =>
- createStyles({
- seeMore: {
- marginTop: theme.spacing(3),
- },
- paper: {
- display: "flex",
- overflow: "auto",
- flexDirection: "column",
- },
-
- addSideBar: {
- width: "320px",
- padding: "20px",
- },
- errorBlock: {
- color: "red",
- },
- tableToolbar: {
- paddingLeft: theme.spacing(2),
- paddingRight: theme.spacing(0),
- },
- minTableHeader: {
- color: "#393939",
- "& tr": {
- "& th": {
- fontWeight: "bold",
- },
- },
- },
- ...actionsTray,
- ...searchField,
- ...containerForHeader(theme.spacing(4)),
- });
-
-interface IRemoteListBucketsProps {
- classes: any;
-}
-
-const RemoteBucketsList = ({ classes }: IRemoteListBucketsProps) => {
- const [records, setRecords] = useState([]);
- const [totalRecords, setTotalRecords] = useState(0);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState("");
- const [addScreenOpen, setAddScreenOpen] = useState(false);
- const [deleteScreenOpen, setDeleteOpen] = useState(false);
- const [page, setPage] = useState(0);
- const [rowsPerPage, setRowsPerPage] = useState(10);
- const [selectedBucket, setSelectedBucket] = useState({
- remoteARN: "",
- accessKey: "",
- name: "",
- secretKey: "",
- service: "",
- sourceBucket: "",
- status: "",
- targetBucket: "",
- targetURL: "",
- });
- const [filterBuckets, setFilterBuckets] = useState("");
-
- useEffect(() => {
- if (loading) {
- fetchRecords();
- }
- }, [loading]);
-
- const closeAddModalAndRefresh = () => {
- setAddScreenOpen(false);
- setLoading(true);
- };
-
- const closeDeleteModalAndRefresh = (reload: boolean) => {
- setDeleteOpen(false);
-
- if (reload) {
- setLoading(true);
- }
- };
-
- const fetchRecords = () => {
- const offset = page * rowsPerPage;
- api
- .invoke("GET", `/api/v1/remote-buckets`)
- .then((res: IRemoteBucketsResponse) => {
- setLoading(false);
- setRecords(res.buckets || []);
- setTotalRecords(!res.buckets ? 0 : res.total);
- setError("");
- // if we get 0 results, and page > 0 , go down 1 page
- if (
- (res.buckets === undefined ||
- res.buckets == null ||
- res.buckets.length === 0) &&
- page > 0
- ) {
- const newPage = page - 1;
- setPage(newPage);
- setLoading(true);
- }
- })
- .catch((err: any) => {
- setLoading(false);
- setError(err);
- });
- };
-
- const offset = page * rowsPerPage;
-
- const handleChangePage = (event: unknown, newPage: number) => {
- setPage(newPage);
- };
-
- const handleChangeRowsPerPage = (
- event: React.ChangeEvent
- ) => {
- const rPP = parseInt(event.target.value, 10);
- setPage(0);
- setRowsPerPage(rPP);
- };
-
- const confirmDeleteRemoteBucket = (arnRemoteBucket: IRemoteBucket) => {
- setSelectedBucket(arnRemoteBucket);
- setDeleteOpen(true);
- };
-
- const tableActions = [{ type: "delete", onClick: confirmDeleteRemoteBucket }];
-
- const filteredRecords = records
- .slice(offset, offset + rowsPerPage)
- .filter((b: IRemoteBucket) => {
- if (filterBuckets === "") {
- return true;
- } else {
- if (b.name.indexOf(filterBuckets) >= 0) {
- return true;
- } else {
- return false;
- }
- }
- });
-
- return (
-
- {addScreenOpen && (
- {
- closeAddModalAndRefresh();
- }}
- />
- )}
- {deleteScreenOpen && (
- {
- closeDeleteModalAndRefresh(reload);
- }}
- deleteOpen={deleteScreenOpen}
- />
- )}
-
-
-
-
- {
- setFilterBuckets(val.target.value);
- }}
- InputProps={{
- disableUnderline: true,
- startAdornment: (
-
-
-
- ),
- }}
- />
- }
- onClick={() => {
- setAddScreenOpen(true);
- }}
- >
- Create Remote Bucket
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default withStyles(styles)(RemoteBucketsList);
diff --git a/portal-ui/src/screens/Console/RemoteBuckets/types.ts b/portal-ui/src/screens/Console/RemoteBuckets/types.ts
deleted file mode 100644
index 35ac9fadc..000000000
--- a/portal-ui/src/screens/Console/RemoteBuckets/types.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// This file is part of MinIO Console Server
-// Copyright (c) 2020 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 .
-
-export interface IRemoteBucketsResponse {
- buckets: IRemoteBucket[];
- total: number;
-}
-
-export interface IRemoteBucket {
- name: string;
- accessKey: string;
- secretKey: string;
- sourceBucket: string;
- targetURL: string;
- targetBucket: string;
- remoteARN: string;
- status: string;
- service: string;
-}