Add size info to bucket list api (#122)

Using madmin.AccountUsageInfo since that api
includes size already.
Also includes integration with UI.
This commit is contained in:
César Nieto
2020-05-18 13:36:18 -07:00
committed by GitHub
parent 35c3b53a23
commit e8491d80cb
8 changed files with 214 additions and 188 deletions

4
go.mod
View File

@@ -17,8 +17,8 @@ require (
github.com/jessevdk/go-flags v1.4.0
github.com/json-iterator/go v1.1.9
github.com/minio/cli v1.22.0
github.com/minio/mc v0.0.0-20200515191050-09c31c4ab28c
github.com/minio/minio v0.0.0-20200501193630-d1c8e9f31ba0
github.com/minio/mc v0.0.0-20200515235434-3b479cf92ed6
github.com/minio/minio v0.0.0-20200516011754-9cac385aecdb
github.com/minio/minio-go/v6 v6.0.56-0.20200502013257-a81c8c13cc3f
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/satori/go.uuid v1.2.0

33
go.sum
View File

@@ -239,6 +239,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -338,12 +339,16 @@ github.com/klauspost/compress v1.10.3 h1:OP96hzwJVBIHYU52pVTI6CczrxPvrGfgqF9N5eT
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/cpuid v1.2.2 h1:1xAgYebNnsb9LKCdLOvFWtAxGU/33mjJtyOVbmUa0Us=
github.com/klauspost/cpuid v1.2.2/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.2.4 h1:EBfaK0SWSwk+fgk6efYFWdzl8MwRWoOO1gkmiaTXPW4=
github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.1 h1:oIPZROsWuPHpOdMVWLuJZXwgjhrW8r1yEX8UqMyeNHM=
github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/readahead v1.3.1 h1:QqXNYvm+VvqYcbrRT4LojUciM0XrznFRIDrbHiJtu/0=
github.com/klauspost/readahead v1.3.1/go.mod h1:AH9juHzNH7xqdqFHrMRSHeH2Ps+vFf+kblDqzPFiLJg=
github.com/klauspost/reedsolomon v1.9.3 h1:N/VzgeMfHmLc+KHMD1UL/tNkfXAt8FnUqlgXGIduwAY=
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
github.com/klauspost/reedsolomon v1.9.7 h1:+azeqnT4iNG9UEcWC+7utJ4xXQ9S8pSlkZor0DOArEQ=
github.com/klauspost/reedsolomon v1.9.7/go.mod h1:+8WD025Xpby8/kG5h/HDPIFhiiuGEtZOKw+5Y4drAD8=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -399,15 +404,14 @@ github.com/minio/highwayhash v1.0.0 h1:iMSDhgUILCr0TNm8LWlSjF8N0ZIj2qbO8WHp6Q/J2
github.com/minio/highwayhash v1.0.0/go.mod h1:xQboMTeM9nY9v/LlAOxFctujiv5+Aq2hR5dxBpaMbdc=
github.com/minio/lsync v1.0.1 h1:AVvILxA976xc27hstd1oR+X9PQG0sPSom1MNb1ImfUs=
github.com/minio/lsync v1.0.1/go.mod h1:tCFzfo0dlvdGl70IT4IAK/5Wtgb0/BrTmo/jE8pArKA=
github.com/minio/mc v0.0.0-20200515191050-09c31c4ab28c h1:G4ZTNwiiJ73folxqNXZpWQofxus2fGJG7hKxYNrtvRM=
github.com/minio/mc v0.0.0-20200515191050-09c31c4ab28c/go.mod h1:U3Jgk0bcSjn+QPUMisrS6nxCWOoQ6rYWSvLCB30apuU=
github.com/minio/mc v0.0.0-20200515235434-3b479cf92ed6 h1:2SrKe2vLDLwvnYkYrJelrzyGW8t/8HCbr9yDsw+8XSI=
github.com/minio/mc v0.0.0-20200515235434-3b479cf92ed6/go.mod h1:U3Jgk0bcSjn+QPUMisrS6nxCWOoQ6rYWSvLCB30apuU=
github.com/minio/minio v0.0.0-20200421050159-282c9f790a03/go.mod h1:zBua5AiljGs1Irdl2XEyiJjvZVCVDIG8gjozzRBcVlw=
github.com/minio/minio v0.0.0-20200501193630-d1c8e9f31ba0 h1:QxIz36O01LbKqJiz6HKeKCOC2afgydspkpahQ807msY=
github.com/minio/minio v0.0.0-20200501193630-d1c8e9f31ba0/go.mod h1:Vhlqz7Se0EgpgFiVxpvzF4Zz/h2LMx+EPKH96Aera5U=
github.com/minio/minio v0.0.0-20200516011754-9cac385aecdb h1:CQC7D3UDnUycuxhwImcVhMSLet/RbShosAnYcvMtEB8=
github.com/minio/minio v0.0.0-20200516011754-9cac385aecdb/go.mod h1:wymaytM/HELuwdz7BGZHmQ3XKq2SxPsLeGxyOCaCLiA=
github.com/minio/minio-go/v6 v6.0.53 h1:8jzpwiOzZ5Iz7/goFWqNZRICbyWYShbb5rARjrnSCNI=
github.com/minio/minio-go/v6 v6.0.53/go.mod h1:DIvC/IApeHX8q1BAMVCXSXwpmrmM+I+iBvhvztQorfI=
github.com/minio/minio-go/v6 v6.0.55-0.20200424204115-7506d2996b22 h1:nZEve4vdUhwHBoV18zRvPDgjL6NYyDJE5QJvz3l9bRs=
github.com/minio/minio-go/v6 v6.0.55-0.20200424204115-7506d2996b22/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
github.com/minio/minio-go/v6 v6.0.55-0.20200425081427-89eebdef2af0/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
github.com/minio/minio-go/v6 v6.0.56-0.20200502013257-a81c8c13cc3f h1:ifHrI8+exqLi5RztIWWKS5k+Wu+W7DJisVXwNaCH2zs=
github.com/minio/minio-go/v6 v6.0.56-0.20200502013257-a81c8c13cc3f/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI=
github.com/minio/parquet-go v0.0.0-20200414234858-838cfa8aae61 h1:pUSI/WKPdd77gcuoJkSzhJ4wdS8OMDOsOu99MtpXEQA=
@@ -609,11 +613,19 @@ go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.11.0 h1:gSmpCfs+R47a4yQPAI4xJ0IPDLTRGXskm6UelqNXpqE=
go.uber.org/zap v1.11.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
golang.org/x/arch v0.0.0-20190909030613-46d78d1859ac/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -622,6 +634,7 @@ golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -637,6 +650,9 @@ golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -717,8 +733,11 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190914235951-31e00f45c22e h1:nOOVVcLC+/3MeovP40q5lCiWmP1Z1DaN8yn8ngU63hw=
golang.org/x/tools v0.0.0-20190914235951-31e00f45c22e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 h1:Xvf3ZQTm5bjXPxhI7g+dwqsCqadK1rcNtwtszuatetk=
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -788,4 +807,6 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

File diff suppressed because one or more lines are too long

View File

@@ -14,7 +14,17 @@
// 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/>.
export const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
export const units = [
"B",
"KiB",
"MiB",
"GiB",
"TiB",
"PiB",
"EiB",
"ZiB",
"YiB",
];
export const niceBytes = (x: string) => {
let l = 0,
n = parseInt(x, 10) || 0;

View File

@@ -30,49 +30,50 @@ import AddBucket from "./AddBucket";
import DeleteBucket from "./DeleteBucket";
import { MinTablePaginationActions } from "../../../../common/MinTablePaginationActions";
import { CreateIcon } from "../../../../icons";
import { niceBytes } from "../../../../common/utils";
const styles = (theme: Theme) =>
createStyles({
seeMore: {
marginTop: theme.spacing(3)
marginTop: theme.spacing(3),
},
paper: {
display: "flex",
overflow: "auto",
flexDirection: "column"
flexDirection: "column",
},
addSideBar: {
width: "320px",
padding: "20px"
padding: "20px",
},
errorBlock: {
color: "red"
color: "red",
},
tableToolbar: {
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(0)
paddingRight: theme.spacing(0),
},
minTableHeader: {
color: "#393939",
"& tr": {
"& th": {
fontWeight: "bold"
}
}
fontWeight: "bold",
},
},
},
actionsTray: {
textAlign: "right",
"& button": {
marginLeft: 10
}
marginLeft: 10,
},
},
searchField: {
background: "#FFFFFF",
padding: 12,
borderRadius: 5,
boxShadow: "0px 3px 6px #00000012"
}
boxShadow: "0px 3px 6px #00000012",
},
});
interface IListBucketsProps {
@@ -108,7 +109,7 @@ class ListBuckets extends React.Component<
rowsPerPage: 10,
deleteOpen: false,
selectedBucket: "",
filterBuckets: ""
filterBuckets: "",
};
fetchRecords() {
@@ -122,7 +123,7 @@ class ListBuckets extends React.Component<
loading: false,
records: res.buckets || [],
totalRecords: !res.buckets ? 0 : res.total,
error: ""
error: "",
});
// if we get 0 results, and page > 0 , go down 1 page
if (
@@ -174,7 +175,7 @@ class ListBuckets extends React.Component<
rowsPerPage,
deleteOpen,
selectedBucket,
filterBuckets
filterBuckets,
} = this.state;
const offset = page * rowsPerPage;
@@ -196,7 +197,7 @@ class ListBuckets extends React.Component<
const tableActions = [
{ type: "view", to: `/buckets`, sendOnlyId: true },
{ type: "delete", onClick: confirmDeleteBucket, sendOnlyId: true }
{ type: "delete", onClick: confirmDeleteBucket, sendOnlyId: true },
];
const displayParsedDate = (date: string) => {
@@ -249,9 +250,9 @@ class ListBuckets extends React.Component<
className={classes.searchField}
id="search-resource"
label=""
onChange={val => {
onChange={(val) => {
this.setState({
filterBuckets: val.target.value
filterBuckets: val.target.value,
});
}}
InputProps={{
@@ -260,7 +261,7 @@ class ListBuckets extends React.Component<
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
)
),
}}
/>
<Button
@@ -269,7 +270,7 @@ class ListBuckets extends React.Component<
startIcon={<CreateIcon />}
onClick={() => {
this.setState({
addScreenOpen: true
addScreenOpen: true,
});
}}
>
@@ -287,8 +288,13 @@ class ListBuckets extends React.Component<
{
label: "Creation Date",
elementKey: "creation_date",
renderFunction: displayParsedDate
}
renderFunction: displayParsedDate,
},
{
label: "Size",
elementKey: "size",
renderFunction: niceBytes,
},
]}
isLoading={loading}
records={filteredRecords}
@@ -302,11 +308,11 @@ class ListBuckets extends React.Component<
page: page,
SelectProps: {
inputProps: { "aria-label": "rows per page" },
native: true
native: true,
},
onChangePage: handleChangePage,
onChangeRowsPerPage: handleChangeRowsPerPage,
ActionsComponent: MinTablePaginationActions
ActionsComponent: MinTablePaginationActions,
}}
/>
</Grid>

View File

@@ -84,6 +84,7 @@ type MinioAdmin interface {
stopProfiling(ctx context.Context) (io.ReadCloser, error)
serviceTrace(ctx context.Context, allTrace, errTrace bool) <-chan madmin.ServiceTraceInfo
getLogs(ctx context.Context, node string, lineCnt int, logKind string) <-chan madmin.LogInfo
accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error)
// Service Accounts
addServiceAccount(ctx context.Context, policy *iampolicy.Policy) (mauth.Credentials, error)
listServiceAccounts(ctx context.Context) (madmin.ListServiceAccountsResp, error)
@@ -228,6 +229,11 @@ func (ac adminClient) deleteServiceAccount(ctx context.Context, serviceAccount s
return ac.client.DeleteServiceAccount(ctx, serviceAccount)
}
// implements madmin.AccountingUsageInfo()
func (ac adminClient) accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error) {
return ac.client.AccountUsageInfo(ctx)
}
func newMAdminClient(jwt string) (*madmin.AdminClient, error) {
claims, err := auth.JWTAuthenticate(jwt)
if err != nil {

View File

@@ -82,22 +82,17 @@ func registerBucketsHandlers(api *operations.McsAPI) {
})
}
// listBuckets fetches a list of all buckets from MinIO Servers
func listBuckets(ctx context.Context, client MinioClient) ([]*models.Bucket, error) {
// Get list of all buckets owned by an authenticated user.
// This call requires explicit authentication, no anonymous requests are
// allowed for listing buckets.
buckets, err := client.listBucketsWithContext(ctx)
// getaAcountUsageInfo fetches a list of all buckets allowed to that particular client from MinIO Servers
func getaAcountUsageInfo(ctx context.Context, client MinioAdmin) ([]*models.Bucket, error) {
info, err := client.accountUsageInfo(ctx)
if err != nil {
return []*models.Bucket{}, err
}
var bucketInfos []*models.Bucket
for _, bucket := range buckets {
bucketElem := &models.Bucket{Name: swag.String(bucket.Name), CreationDate: bucket.CreationDate.String()}
for _, bucket := range info.Buckets {
bucketElem := &models.Bucket{Name: swag.String(bucket.Name), CreationDate: bucket.Created.String(), Size: int64(bucket.Size)}
bucketInfos = append(bucketInfos, bucketElem)
}
return bucketInfos, nil
}
@@ -105,20 +100,21 @@ func listBuckets(ctx context.Context, client MinioClient) ([]*models.Bucket, err
func getListBucketsResponse(sessionID string) (*models.ListBucketsResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
mClient, err := newMinioClient(sessionID)
mAdmin, err := newMAdminClient(sessionID)
if err != nil {
log.Println("error creating MinIO Client:", err)
log.Println("error creating Madmin Client:", err)
return nil, err
}
// create a minioClient interface implementation
// defining the client to be used
minioClient := minioClient{client: mClient}
buckets, err := listBuckets(ctx, minioClient)
adminClient := adminClient{client: mAdmin}
buckets, err := getaAcountUsageInfo(ctx, adminClient)
if err != nil {
log.Println("error listing buckets:", err)
log.Println("error accountingUsageInfo:", err)
return nil, err
}
// serialize output
listBucketsResponse := &models.ListBucketsResponse{
Buckets: buckets,

View File

@@ -27,6 +27,7 @@ import (
"github.com/go-openapi/swag"
"github.com/minio/mcs/models"
"github.com/minio/minio-go/v6"
"github.com/minio/minio/pkg/madmin"
"github.com/stretchr/testify/assert"
)
@@ -66,41 +67,50 @@ func (mc minioClientMock) getBucketPolicy(bucketName string) (string, error) {
return minioGetBucketPolicyMock(bucketName)
}
var minioAccountUsageInfoMock func(ctx context.Context) (madmin.AccountUsageInfo, error)
// mock function of dataUsageInfo() needed for list bucket's usage
func (ac adminClientMock) accountUsageInfo(ctx context.Context) (madmin.AccountUsageInfo, error) {
return minioAccountUsageInfoMock(ctx)
}
func TestListBucket(t *testing.T) {
assert := assert.New(t)
minClient := minioClientMock{}
adminClient := adminClientMock{}
ctx := context.Background()
// Test-1 : listBuckets() Get response from minio client with two buckets and return the same number on listBuckets()
// mock minIO client
mockBucketList := []minio.BucketInfo{
minio.BucketInfo{Name: "bucket-1", CreationDate: time.Now()},
minio.BucketInfo{Name: "bucket-2", CreationDate: time.Now().Add(time.Hour * 1)},
// Test-1 : getaAcountUsageInfo() Get response from minio client with two buckets
mockBucketList := madmin.AccountUsageInfo{
AccountName: "test",
Buckets: []madmin.BucketUsageInfo{
madmin.BucketUsageInfo{Name: "bucket-1", Created: time.Now(), Size: 1024},
madmin.BucketUsageInfo{Name: "bucket-2", Created: time.Now().Add(time.Hour * 1), Size: 0},
},
}
// mock function response from listBucketsWithContext(ctx)
minioListBucketsWithContextMock = func(ctx context.Context) ([]minio.BucketInfo, error) {
minioAccountUsageInfoMock = func(ctx context.Context) (madmin.AccountUsageInfo, error) {
return mockBucketList, nil
}
// get list buckets response this response should have Name, CreationDate, Size and Access
// as part of of each bucket
function := "listBuckets()"
bucketList, err := listBuckets(ctx, minClient)
function := "getaAcountUsageInfo()"
bucketList, err := getaAcountUsageInfo(ctx, adminClient)
if err != nil {
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
}
// verify length of buckets is correct
assert.Equal(len(mockBucketList), len(bucketList), fmt.Sprintf("Failed on %s: length of bucket's lists is not the same", function))
assert.Equal(len(mockBucketList.Buckets), len(bucketList), fmt.Sprintf("Failed on %s: length of bucket's lists is not the same", function))
for i, b := range bucketList {
assert.Equal(mockBucketList[i].Name, *b.Name)
assert.Equal(mockBucketList[i].CreationDate.String(), b.CreationDate)
assert.Equal(mockBucketList.Buckets[i].Name, *b.Name)
assert.Equal(mockBucketList.Buckets[i].Created.String(), b.CreationDate)
assert.Equal(mockBucketList.Buckets[i].Name, *b.Name)
assert.Equal(int64(mockBucketList.Buckets[i].Size), b.Size)
}
// Test-2 : listBuckets() Return and see that the error is handled correctly and returned
minioListBucketsWithContextMock = func(ctx context.Context) ([]minio.BucketInfo, error) {
return nil, errors.New("error")
// Test-2 : getaAcountUsageInfo() Return and see that the error is handled correctly and returned
minioAccountUsageInfoMock = func(ctx context.Context) (madmin.AccountUsageInfo, error) {
return madmin.AccountUsageInfo{}, errors.New("error")
}
_, err = listBuckets(ctx, minClient)
_, err = getaAcountUsageInfo(ctx, adminClient)
if assert.Error(err) {
assert.Equal("error", err.Error())
}