diff --git a/go.mod b/go.mod index 761290ccbc..0aec07ba1c 100644 --- a/go.mod +++ b/go.mod @@ -25,14 +25,20 @@ require ( github.com/minio/selfupdate v0.3.1 github.com/mitchellh/go-homedir v1.1.0 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect + github.com/rs/xid v1.2.1 github.com/secure-io/sio-go v0.3.1 github.com/stretchr/testify v1.6.1 github.com/unrolled/secure v1.0.7 golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392 - golang.org/x/net v0.0.0-20201216054612-986b41b23924 + golang.org/x/net v0.0.0-20201224014010-6772e930b67b golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d gopkg.in/yaml.v2 v2.3.0 k8s.io/api v0.20.2 k8s.io/apimachinery v0.20.2 k8s.io/client-go v0.20.2 ) + +replace ( + github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243 => github.com/krisis/mc v0.0.0-20210212174421-7b633602cb9b + github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f => github.com/poornas/minio v0.0.0-20210222213933-192ae7d4df2c +) diff --git a/go.sum b/go.sum index bcaf5761ce..f086e53455 100644 --- a/go.sum +++ b/go.sum @@ -813,6 +813,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/krisis/mc v0.0.0-20210212174421-7b633602cb9b h1:qmBvB+r7Ky+gd9+ggS5wwddPEC92FLfqlw792ep6/YU= +github.com/krisis/mc v0.0.0-20210212174421-7b633602cb9b/go.mod h1:2tPdLS3Kbf82Oy1x/H2D1jv/Cpn4WBuqn9xgeqaITZ0= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -863,9 +865,8 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= @@ -886,16 +887,14 @@ github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/minio/kes v0.11.0 h1:8ma6OCVSxKT50b1uYXLJro3m7PmZtCLxBaTddQexI5k= github.com/minio/kes v0.11.0/go.mod h1:mTF1Bv8YVEtQqF/B7Felp4tLee44Pp+dgI0rhCvgNg8= -github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243 h1:V0EoJ/I/p86J8FH2zuOSTsTzNzDXQX4xZKvBwBLS/Qk= -github.com/minio/mc v0.0.0-20210301162250-f9d36f9b5243/go.mod h1:nkHp/atLUKkhML5YGfvaDDFqlcBmuii7s9Dbk3ulB1Q= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/md5-simd v1.1.1 h1:9ojcLbuZ4gXbB2sX53MKn8JUZ0sB/2wfwsEcRw+I08U= github.com/minio/md5-simd v1.1.1/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/minio v0.0.0-20210128013121-e79829b5b368/go.mod h1:6jySvEwvfCfr9SphRrAb+TMtEXRgRJ4sb79UKFJWmFM= -github.com/minio/minio v0.0.0-20210301081546-0b9c17443eb8/go.mod h1:E7ngQWKJdbRG9dqHZ86lnhGS0RxqtEJTnWDEM/P9BQs= -github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f h1:dAFaii7oqV0Mu9rUNfsgKdE10aZADSgIXoK5saLVeOE= -github.com/minio/minio v0.0.0-20210301203133-e8d8dfa3ae8f/go.mod h1:E7ngQWKJdbRG9dqHZ86lnhGS0RxqtEJTnWDEM/P9BQs= +github.com/minio/minio v0.0.0-20210209035817-3d74efa6b112/go.mod h1:ANdaxQOv4GfNOfz3guTl5You1yyD3xM1gQWl+uIQrIk= github.com/minio/minio-go/v7 v7.0.8-0.20210127003153-c40722862654/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc= +github.com/minio/minio-go/v7 v7.0.8/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc= +github.com/minio/minio-go/v7 v7.0.9-0.20210210235136-83423dddb072/go.mod h1:pEZBUa+L2m9oECoIA6IcSK8bv/qggtQVLovjeKK5jYc= github.com/minio/minio-go/v7 v7.0.10 h1:1oUKe4EOPUEhw2qnPQaPsJ0lmVTYLFu03SiItauXs94= github.com/minio/minio-go/v7 v7.0.10/go.mod h1:td4gW1ldOsj1PbSNS+WYK43j+P1XVhX/8W8awaYlBFo= github.com/minio/operator v0.0.0-20210201110528-753019b838b4 h1:2TtnWOrVkMC8N/wLWwlnsEIMOHpZOIsF8JZ0cPDI1m0= @@ -1028,6 +1027,7 @@ github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bA github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/philhofer/fwd v1.1.1 h1:GdGcTjf5RNAxwS4QLsiMzJYj5KEvPJD3Abr261yRQXQ= github.com/philhofer/fwd v1.1.1/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -1045,6 +1045,8 @@ github.com/pkg/xattr v0.4.1/go.mod h1:W2cGD0TBEus7MkUgv0tNZ9JutLtVO3cXu+IBRuHqnF github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/poornas/minio v0.0.0-20210222213933-192ae7d4df2c h1:ktdOdAPEt4ysKWjYi0nQG8OCNMA+4Pf5MyHOxrdO2SM= +github.com/poornas/minio v0.0.0-20210222213933-192ae7d4df2c/go.mod h1:4qoUPZRkHBm2XX2d9XFCbYnzMMPALtuh608GRQTp6qw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= @@ -1088,6 +1090,7 @@ github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-ruleguard v0.1.2-0.20200318202121-b00d7a75d3d8/go.mod h1:CGFX09Ci3pq9QZdj86B+VGIdNj4VyCo2iPOGS9esB/k= +github.com/quasilyte/go-ruleguard v0.2.1/go.mod h1:hN2rVc/uS4bQhQKTio2XaSJSafJwqBUWWwtssT3cQmc= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1128,8 +1131,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/gopsutil v3.20.11+incompatible h1:LJr4ZQK4mPpIV5gOa4jCOKOGb4ty4DZO54I4FGqIpto= github.com/shirou/gopsutil v3.20.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.21.1 h1:dA72XXj5WOXIZkAL2iYTKRVcNOOqh4yfLn9Rm7t8BMM= -github.com/shirou/gopsutil/v3 v3.21.1/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkUcCLlYhZzdr/4= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -1212,6 +1213,7 @@ github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/tinylib/msgp v1.1.3 h1:3giwAkmtaEDLSV0MdO1lDLuPgklgPzmk8H9+So2BVfA= github.com/tinylib/msgp v1.1.3/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= @@ -1222,6 +1224,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tommy-muehle/go-mnd v1.1.1/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= github.com/tommy-muehle/go-mnd v1.3.1-0.20200224220436-e6f9a994e8fa/go.mod h1:dSUh0FtTP8VhvkL1S+gUR1OKd9ZnSaozuI6r3m6wOig= +github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -1422,8 +1425,9 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY= golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1507,7 +1511,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201024232916-9f70ab9862d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1614,6 +1617,7 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20201105001634-bc3cf281b174/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210115202250-e0d201561e39/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= diff --git a/models/add_bucket_lifecycle.go b/models/add_bucket_lifecycle.go new file mode 100644 index 0000000000..ccc4e3c841 --- /dev/null +++ b/models/add_bucket_lifecycle.go @@ -0,0 +1,93 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// AddBucketLifecycle add bucket lifecycle +// +// swagger:model addBucketLifecycle +type AddBucketLifecycle struct { + + // Non required, toggle to disable or enable rule + Disable bool `json:"disable,omitempty"` + + // Non required, toggle to disable or enable rule + ExpiredObjectDeleteMarker bool `json:"expired_object_delete_marker,omitempty"` + + // Required in case of expiry_days or transition fields are not set. it defines an expiry date for ILM + ExpiryDate string `json:"expiry_date,omitempty"` + + // Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM + ExpiryDays int32 `json:"expiry_days,omitempty"` + + // Non required, can be set in case of expiration is enabled + NoncurrentversionExpirationDays int32 `json:"noncurrentversion_expiration_days,omitempty"` + + // Non required, can be set in case of transition is enabled + NoncurrentversionTransitionDays int32 `json:"noncurrentversion_transition_days,omitempty"` + + // Non required, can be set in case of transition is enabled + NoncurrentversionTransitionStorageClass string `json:"noncurrentversion_transition_storage_class,omitempty"` + + // Non required field, it matches a prefix to perform ILM operations on it + Prefix string `json:"prefix,omitempty"` + + // Required only in case of transition is set. it refers to a tier + StorageClass string `json:"storage_class,omitempty"` + + // Non required field, tags to match ILM files + Tags string `json:"tags,omitempty"` + + // Required in case of transition_days or expiry fields are not set. it defines a transition date for ILM + TransitionDate string `json:"transition_date,omitempty"` + + // Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM + TransitionDays int32 `json:"transition_days,omitempty"` +} + +// Validate validates this add bucket lifecycle +func (m *AddBucketLifecycle) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *AddBucketLifecycle) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *AddBucketLifecycle) UnmarshalBinary(b []byte) error { + var res AddBucketLifecycle + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/bucket_lifecycle_response.go b/models/bucket_lifecycle_response.go new file mode 100644 index 0000000000..852561b87d --- /dev/null +++ b/models/bucket_lifecycle_response.go @@ -0,0 +1,97 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// BucketLifecycleResponse bucket lifecycle response +// +// swagger:model bucketLifecycleResponse +type BucketLifecycleResponse struct { + + // lifecycle + Lifecycle []*ObjectBucketLifecycle `json:"lifecycle"` +} + +// Validate validates this bucket lifecycle response +func (m *BucketLifecycleResponse) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateLifecycle(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *BucketLifecycleResponse) validateLifecycle(formats strfmt.Registry) error { + + if swag.IsZero(m.Lifecycle) { // not required + return nil + } + + for i := 0; i < len(m.Lifecycle); i++ { + if swag.IsZero(m.Lifecycle[i]) { // not required + continue + } + + if m.Lifecycle[i] != nil { + if err := m.Lifecycle[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("lifecycle" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *BucketLifecycleResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *BucketLifecycleResponse) UnmarshalBinary(b []byte) error { + var res BucketLifecycleResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/expiration_response.go b/models/expiration_response.go new file mode 100644 index 0000000000..90d63808f5 --- /dev/null +++ b/models/expiration_response.go @@ -0,0 +1,66 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// ExpirationResponse expiration response +// +// swagger:model expirationResponse +type ExpirationResponse struct { + + // date + Date string `json:"date,omitempty"` + + // days + Days int64 `json:"days,omitempty"` + + // delete marker + DeleteMarker bool `json:"delete_marker,omitempty"` +} + +// Validate validates this expiration response +func (m *ExpirationResponse) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *ExpirationResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ExpirationResponse) UnmarshalBinary(b []byte) error { + var res ExpirationResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/lifecycle_tag.go b/models/lifecycle_tag.go new file mode 100644 index 0000000000..5de9ba884f --- /dev/null +++ b/models/lifecycle_tag.go @@ -0,0 +1,63 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// LifecycleTag lifecycle tag +// +// swagger:model lifecycleTag +type LifecycleTag struct { + + // key + Key string `json:"key,omitempty"` + + // value + Value string `json:"value,omitempty"` +} + +// Validate validates this lifecycle tag +func (m *LifecycleTag) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *LifecycleTag) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *LifecycleTag) UnmarshalBinary(b []byte) error { + var res LifecycleTag + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/object_bucket_lifecycle.go b/models/object_bucket_lifecycle.go new file mode 100644 index 0000000000..d47e844415 --- /dev/null +++ b/models/object_bucket_lifecycle.go @@ -0,0 +1,156 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// ObjectBucketLifecycle object bucket lifecycle +// +// swagger:model objectBucketLifecycle +type ObjectBucketLifecycle struct { + + // expiration + Expiration *ExpirationResponse `json:"expiration,omitempty"` + + // id + ID string `json:"id,omitempty"` + + // prefix + Prefix string `json:"prefix,omitempty"` + + // status + Status string `json:"status,omitempty"` + + // tags + Tags []*LifecycleTag `json:"tags"` + + // transition + Transition *TransitionResponse `json:"transition,omitempty"` +} + +// Validate validates this object bucket lifecycle +func (m *ObjectBucketLifecycle) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateExpiration(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTags(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTransition(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *ObjectBucketLifecycle) validateExpiration(formats strfmt.Registry) error { + + if swag.IsZero(m.Expiration) { // not required + return nil + } + + if m.Expiration != nil { + if err := m.Expiration.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("expiration") + } + return err + } + } + + return nil +} + +func (m *ObjectBucketLifecycle) validateTags(formats strfmt.Registry) error { + + if swag.IsZero(m.Tags) { // not required + return nil + } + + for i := 0; i < len(m.Tags); i++ { + if swag.IsZero(m.Tags[i]) { // not required + continue + } + + if m.Tags[i] != nil { + if err := m.Tags[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tags" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *ObjectBucketLifecycle) validateTransition(formats strfmt.Registry) error { + + if swag.IsZero(m.Transition) { // not required + return nil + } + + if m.Transition != nil { + if err := m.Transition.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("transition") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *ObjectBucketLifecycle) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *ObjectBucketLifecycle) UnmarshalBinary(b []byte) error { + var res ObjectBucketLifecycle + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/session_response.go b/models/session_response.go index 847ed2fd49..e72c252f0f 100644 --- a/models/session_response.go +++ b/models/session_response.go @@ -36,6 +36,9 @@ import ( // swagger:model sessionResponse type SessionResponse struct { + // features + Features []string `json:"features"` + // operator Operator bool `json:"operator,omitempty"` diff --git a/models/tier.go b/models/tier.go new file mode 100644 index 0000000000..a92e15ce85 --- /dev/null +++ b/models/tier.go @@ -0,0 +1,198 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "encoding/json" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// Tier tier +// +// swagger:model tier +type Tier struct { + + // azure + Azure *TierAzure `json:"azure,omitempty"` + + // gcs + Gcs *TierGcs `json:"gcs,omitempty"` + + // s3 + S3 *TierS3 `json:"s3,omitempty"` + + // type + // Enum: [s3 gcs azure unsupported] + Type string `json:"type,omitempty"` +} + +// Validate validates this tier +func (m *Tier) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateAzure(formats); err != nil { + res = append(res, err) + } + + if err := m.validateGcs(formats); err != nil { + res = append(res, err) + } + + if err := m.validateS3(formats); err != nil { + res = append(res, err) + } + + if err := m.validateType(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *Tier) validateAzure(formats strfmt.Registry) error { + + if swag.IsZero(m.Azure) { // not required + return nil + } + + if m.Azure != nil { + if err := m.Azure.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("azure") + } + return err + } + } + + return nil +} + +func (m *Tier) validateGcs(formats strfmt.Registry) error { + + if swag.IsZero(m.Gcs) { // not required + return nil + } + + if m.Gcs != nil { + if err := m.Gcs.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("gcs") + } + return err + } + } + + return nil +} + +func (m *Tier) validateS3(formats strfmt.Registry) error { + + if swag.IsZero(m.S3) { // not required + return nil + } + + if m.S3 != nil { + if err := m.S3.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("s3") + } + return err + } + } + + return nil +} + +var tierTypeTypePropEnum []interface{} + +func init() { + var res []string + if err := json.Unmarshal([]byte(`["s3","gcs","azure","unsupported"]`), &res); err != nil { + panic(err) + } + for _, v := range res { + tierTypeTypePropEnum = append(tierTypeTypePropEnum, v) + } +} + +const ( + + // TierTypeS3 captures enum value "s3" + TierTypeS3 string = "s3" + + // TierTypeGcs captures enum value "gcs" + TierTypeGcs string = "gcs" + + // TierTypeAzure captures enum value "azure" + TierTypeAzure string = "azure" + + // TierTypeUnsupported captures enum value "unsupported" + TierTypeUnsupported string = "unsupported" +) + +// prop value enum +func (m *Tier) validateTypeEnum(path, location string, value string) error { + if err := validate.EnumCase(path, location, value, tierTypeTypePropEnum, true); err != nil { + return err + } + return nil +} + +func (m *Tier) validateType(formats strfmt.Registry) error { + + if swag.IsZero(m.Type) { // not required + return nil + } + + // value enum + if err := m.validateTypeEnum("type", "body", m.Type); err != nil { + return err + } + + return nil +} + +// MarshalBinary interface implementation +func (m *Tier) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *Tier) UnmarshalBinary(b []byte) error { + var res Tier + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/tier_azure.go b/models/tier_azure.go new file mode 100644 index 0000000000..1e9b50fcc4 --- /dev/null +++ b/models/tier_azure.go @@ -0,0 +1,78 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TierAzure tier azure +// +// swagger:model tier_azure +type TierAzure struct { + + // accountkey + Accountkey string `json:"accountkey,omitempty"` + + // accountname + Accountname string `json:"accountname,omitempty"` + + // bucket + Bucket string `json:"bucket,omitempty"` + + // endpoint + Endpoint string `json:"endpoint,omitempty"` + + // name + Name string `json:"name,omitempty"` + + // prefix + Prefix string `json:"prefix,omitempty"` + + // region + Region string `json:"region,omitempty"` +} + +// Validate validates this tier azure +func (m *TierAzure) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TierAzure) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TierAzure) UnmarshalBinary(b []byte) error { + var res TierAzure + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/tier_credentials_request.go b/models/tier_credentials_request.go new file mode 100644 index 0000000000..9353601ae9 --- /dev/null +++ b/models/tier_credentials_request.go @@ -0,0 +1,66 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TierCredentialsRequest tier credentials request +// +// swagger:model tierCredentialsRequest +type TierCredentialsRequest struct { + + // access key + AccessKey string `json:"access_key,omitempty"` + + // a base64 encoded value + Creds string `json:"creds,omitempty"` + + // secret key + SecretKey string `json:"secret_key,omitempty"` +} + +// Validate validates this tier credentials request +func (m *TierCredentialsRequest) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TierCredentialsRequest) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TierCredentialsRequest) UnmarshalBinary(b []byte) error { + var res TierCredentialsRequest + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/tier_gcs.go b/models/tier_gcs.go new file mode 100644 index 0000000000..e6d6a9970f --- /dev/null +++ b/models/tier_gcs.go @@ -0,0 +1,75 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TierGcs tier gcs +// +// swagger:model tier_gcs +type TierGcs struct { + + // bucket + Bucket string `json:"bucket,omitempty"` + + // creds + Creds string `json:"creds,omitempty"` + + // endpoint + Endpoint string `json:"endpoint,omitempty"` + + // name + Name string `json:"name,omitempty"` + + // prefix + Prefix string `json:"prefix,omitempty"` + + // region + Region string `json:"region,omitempty"` +} + +// Validate validates this tier gcs +func (m *TierGcs) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TierGcs) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TierGcs) UnmarshalBinary(b []byte) error { + var res TierGcs + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/tier_list_response.go b/models/tier_list_response.go new file mode 100644 index 0000000000..7ffbca2782 --- /dev/null +++ b/models/tier_list_response.go @@ -0,0 +1,97 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TierListResponse tier list response +// +// swagger:model tierListResponse +type TierListResponse struct { + + // items + Items []*Tier `json:"items"` +} + +// Validate validates this tier list response +func (m *TierListResponse) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateItems(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *TierListResponse) validateItems(formats strfmt.Registry) error { + + if swag.IsZero(m.Items) { // not required + return nil + } + + for i := 0; i < len(m.Items); i++ { + if swag.IsZero(m.Items[i]) { // not required + continue + } + + if m.Items[i] != nil { + if err := m.Items[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("items" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *TierListResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TierListResponse) UnmarshalBinary(b []byte) error { + var res TierListResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/tier_s3.go b/models/tier_s3.go new file mode 100644 index 0000000000..f69c4105ba --- /dev/null +++ b/models/tier_s3.go @@ -0,0 +1,81 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TierS3 tier s3 +// +// swagger:model tier_s3 +type TierS3 struct { + + // accesskey + Accesskey string `json:"accesskey,omitempty"` + + // bucket + Bucket string `json:"bucket,omitempty"` + + // endpoint + Endpoint string `json:"endpoint,omitempty"` + + // name + Name string `json:"name,omitempty"` + + // prefix + Prefix string `json:"prefix,omitempty"` + + // region + Region string `json:"region,omitempty"` + + // secretkey + Secretkey string `json:"secretkey,omitempty"` + + // storageclass + Storageclass string `json:"storageclass,omitempty"` +} + +// Validate validates this tier s3 +func (m *TierS3) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TierS3) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TierS3) UnmarshalBinary(b []byte) error { + var res TierS3 + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/transition_response.go b/models/transition_response.go new file mode 100644 index 0000000000..a8bbe2683e --- /dev/null +++ b/models/transition_response.go @@ -0,0 +1,66 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// TransitionResponse transition response +// +// swagger:model transitionResponse +type TransitionResponse struct { + + // date + Date string `json:"date,omitempty"` + + // days + Days int64 `json:"days,omitempty"` + + // storage class + StorageClass string `json:"storage_class,omitempty"` +} + +// Validate validates this transition response +func (m *TransitionResponse) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *TransitionResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *TransitionResponse) UnmarshalBinary(b []byte) error { + var res TransitionResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/update_bucket_lifecycle.go b/models/update_bucket_lifecycle.go new file mode 100644 index 0000000000..6f01e82fd9 --- /dev/null +++ b/models/update_bucket_lifecycle.go @@ -0,0 +1,63 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// UpdateBucketLifecycle update bucket lifecycle +// +// swagger:model updateBucketLifecycle +type UpdateBucketLifecycle struct { + + // disable + Disable bool `json:"disable,omitempty"` + + // tags + Tags string `json:"tags,omitempty"` +} + +// Validate validates this update bucket lifecycle +func (m *UpdateBucketLifecycle) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *UpdateBucketLifecycle) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *UpdateBucketLifecycle) UnmarshalBinary(b []byte) error { + var res UpdateBucketLifecycle + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/auth/idp/oauth2/provider.go b/pkg/auth/idp/oauth2/provider.go index 40b61c2f55..f67062b5b3 100644 --- a/pkg/auth/idp/oauth2/provider.go +++ b/pkg/auth/idp/oauth2/provider.go @@ -110,6 +110,14 @@ func NewOauth2ProviderClient(ctx context.Context, scopes []string, httpClient *h if err != nil { return nil, err } + // if google, change scopes + u, err := url.Parse(GetIdpURL()) + if err != nil { + return nil, err + } + if u.Host == "google.com" { + scopes = []string{oidc.ScopeOpenID} + } // If provided scopes are empty we use a default list if len(scopes) == 0 { scopes = []string{oidc.ScopeOpenID, "profile", "app_metadata", "user_metadata", "email"} diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/AddLifecycleModal.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/AddLifecycleModal.tsx new file mode 100644 index 0000000000..97e6b48356 --- /dev/null +++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/AddLifecycleModal.tsx @@ -0,0 +1,469 @@ +// 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 . + +import React, { useState, useEffect, Fragment } from "react"; +import get from "lodash/get"; +import { connect } from "react-redux"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { Button, LinearProgress } from "@material-ui/core"; +import Grid from "@material-ui/core/Grid"; +import { modalBasic } from "../../Common/FormComponents/common/styleLibrary"; +import { setModalErrorSnackMessage } from "../../../../actions"; +import { + ITierResponse, + ITierElement, +} from "../../Configurations/TiersConfiguration/types"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; +import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; +import api from "../../../../common/api"; +import DateSelector from "../../Common/FormComponents/DateSelector/DateSelector"; +import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; +import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector"; +import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; + +interface IReplicationModal { + open: boolean; + closeModalAndRefresh: (refresh: boolean) => any; + classes: any; + bucketName: string; + setModalErrorSnackMessage: typeof setModalErrorSnackMessage; +} + +interface ITiersDropDown { + label: string; + value: string; +} + +const styles = (theme: Theme) => + createStyles({ + minTableHeader: { + color: "#393939", + "& tr": { + "& th": { + fontWeight: "bold", + }, + }, + }, + buttonContainer: { + textAlign: "right", + }, + ...modalBasic, + }); + +const AddLifecycleModal = ({ + open, + closeModalAndRefresh, + classes, + bucketName, + setModalErrorSnackMessage, +}: IReplicationModal) => { + const [loadingTiers, setLoadingTiers] = useState(true); + const [tiersList, setTiersList] = useState([]); + const [addLoading, setAddLoading] = useState(false); + const [prefix, setPrefix] = useState(""); + const [tags, setTags] = useState(""); + const [storageClass, setStorageClass] = useState(""); + const [NCTransitionSC, setNCTransitionSC] = useState(""); + const [expiredObjectDM, setExpiredObjectDM] = useState(false); + const [NCExpirationDays, setNCExpirationDays] = useState("0"); + const [NCTransitionDays, setNCTransitionDays] = useState("0"); + const [ilmType, setIlmType] = useState("expiry"); + const [expiryType, setExpiryType] = useState("date"); + const [expiryDays, setExpiryDays] = useState("0"); + const [expiryDate, setExpiryDate] = useState(""); + const [transitionDays, setTransitionDays] = useState("0"); + const [transitionDate, setTransitionDate] = useState(""); + const [transitionType, setTransitionType] = useState("date"); + const [isFormValid, setIsFormValid] = useState(false); + + useEffect(() => { + if (loadingTiers) { + api + .invoke("GET", `/api/v1/admin/tiers`) + .then((res: ITierResponse) => { + const tiersList: ITierElement[] | null = get(res, "items", []); + + if (tiersList !== null && tiersList.length >= 1) { + const objList = tiersList.map((tier: ITierElement) => { + const tierType = tier.type; + const value = get(tier, `${tierType}.name`, ""); + + return { label: value, value: value }; + }); + + setTiersList(objList); + if (objList.length > 0) { + setStorageClass(objList[0].value); + } + } + setLoadingTiers(false); + }) + .catch((err) => { + setLoadingTiers(false); + }); + } + }, [loadingTiers]); + + useEffect(() => { + let valid = true; + + if (ilmType === "expiry") { + if (expiryType === "date" && expiryDate === "") { + valid = false; + } + if (expiryType === "days" && parseInt(expiryDays) < 1) { + valid = false; + } + } else { + if (transitionType === "date" && transitionDate === "") { + valid = false; + } + if (transitionType === "days" && parseInt(transitionDays) < 1) { + valid = false; + } + + if (storageClass === "") { + valid = false; + } + } + setIsFormValid(valid); + }, [ + ilmType, + expiryType, + expiryDate, + expiryDays, + transitionType, + transitionDate, + transitionDays, + storageClass, + ]); + + const addRecord = () => { + let rules = {}; + + if (ilmType === "expiry") { + let expiry = {}; + + if (expiryType === "date") { + expiry = { + expiry_date: `${expiryDate}T23:59:59Z`, + }; + } else { + expiry = { + expiry_days: parseInt(expiryDays), + }; + } + + rules = { + ...expiry, + noncurrentversion_expiration_days: parseInt(NCExpirationDays), + }; + } else { + let transition = {}; + + if (transitionType === "date") { + transition = { + transition_date: `${transitionDate}T23:59:59Z`, + }; + } else { + transition = { + transition_days: parseInt(transitionDays), + }; + } + + rules = { + ...transition, + noncurrentversion_transition_days: parseInt(NCTransitionDays), + noncurrentversion_transition_storage_class: NCTransitionSC, + storage_class: storageClass, + }; + } + + const lifecycleInsert = { + prefix, + tags, + expired_object_delete_marker: expiredObjectDM, + ...rules, + }; + + api + .invoke( + "POST", + `/api/v1/buckets/${bucketName}/lifecycle`, + lifecycleInsert + ) + .then(() => { + setAddLoading(false); + closeModalAndRefresh(true); + }) + .catch((err) => { + setAddLoading(false); + setModalErrorSnackMessage(err); + }); + }; + + return ( + { + closeModalAndRefresh(false); + }} + title="Add Lifecycle Rule" + > + {loadingTiers && ( + + + + + + )} + + {!loadingTiers && ( +
) => { + e.preventDefault(); + setAddLoading(true); + addRecord(); + }} + > + + +

Lifecycle Configuration

+ + ) => { + setIlmType(e.target.value as string); + }} + selectorOptions={[ + { value: "expiry", label: "Expiry" }, + { value: "transition", label: "Transition" }, + ]} + /> + + {ilmType === "expiry" ? ( + + + ) => { + setExpiryType(e.target.value as string); + }} + selectorOptions={[ + { value: "date", label: "Date" }, + { value: "days", label: "Days" }, + ]} + /> + + + {expiryType === "date" ? ( + { + if (isValid) { + setExpiryDate(date); + } + }} + /> + ) : ( + ) => { + setExpiryDays(e.target.value); + }} + label="Expiry Days" + value={expiryDays} + min="0" + /> + )} + + + ) => { + setNCExpirationDays(e.target.value); + }} + label="Non-current Expiration Days" + value={NCExpirationDays} + min="0" + /> + + + ) : ( + + + ) => { + setTransitionType(e.target.value as string); + }} + selectorOptions={[ + { value: "date", label: "Date" }, + { value: "days", label: "Days" }, + ]} + /> + + + {transitionType === "date" ? ( + { + if (isValid) { + setTransitionDate(date); + } + }} + /> + ) : ( + ) => { + setTransitionDays(e.target.value); + }} + label="Transition Days" + value={transitionDays} + min="0" + /> + )} + + + ) => { + setNCTransitionDays(e.target.value); + }} + label="Non-current Transition Days" + value={NCTransitionDays} + min="0" + /> + + + ) => { + setNCTransitionSC(e.target.value); + }} + placeholder="Set Non-current Version Transition Storage Class" + label="Non-current Version Transition Storage Class" + value={NCTransitionSC} + /> + + + ) => { + setStorageClass(e.target.value as string); + }} + options={tiersList} + /> + + + )} +

File Configuration

+ + ) => { + setPrefix(e.target.value); + }} + label="Prefix" + value={prefix} + /> + + + { + setTags(vl); + }} + keyPlaceholder="Tag Key" + valuePlaceholder="Tag Value" + withBorder + /> + + + ) => { + setExpiredObjectDM(event.target.checked); + }} + label={"Expired Object Delete Marker"} + indicatorLabels={["On", "Off"]} + /> + +
+ + + + {addLoading && ( + + + + )} +
+
+ )} +
+ ); +}; + +const connector = connect(null, { + setModalErrorSnackMessage, +}); + +export default withStyles(styles)(connector(AddLifecycleModal)); diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/DeleteEvent.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/DeleteEvent.tsx index bdcf50c160..69db87f672 100644 --- a/portal-ui/src/screens/Console/Buckets/ViewBucket/DeleteEvent.tsx +++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/DeleteEvent.tsx @@ -93,7 +93,7 @@ const DeleteEvent = ({ {deleteLoading && } - Are you sure you want to delete the this event? + Are you sure you want to delete this event? diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/EditLifecycleConfiguration.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/EditLifecycleConfiguration.tsx new file mode 100644 index 0000000000..31d0f21485 --- /dev/null +++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/EditLifecycleConfiguration.tsx @@ -0,0 +1,197 @@ +// 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 . + +import React, { useEffect, useState } from "react"; +import { connect } from "react-redux"; +import Grid from "@material-ui/core/Grid"; +import { Button, LinearProgress } from "@material-ui/core"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { modalBasic } from "../../Common/FormComponents/common/styleLibrary"; +import { setModalErrorSnackMessage } from "../../../../actions"; +import api from "../../../../common/api"; +import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; +import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector"; +import { LifeCycleItem } from "../types"; + +const styles = (theme: Theme) => + createStyles({ + strongText: { + fontWeight: 700, + }, + keyName: { + marginLeft: 5, + }, + buttonContainer: { + textAlign: "right", + }, + ...modalBasic, + }); + +interface IAddUserContentProps { + classes: any; + closeModalAndRefresh: (reload: boolean) => void; + selectedBucket: string; + lifecycle: LifeCycleItem; + open: boolean; + setModalErrorSnackMessage: typeof setModalErrorSnackMessage; +} + +const EditLifecycleConfiguration = ({ + classes, + closeModalAndRefresh, + selectedBucket, + lifecycle, + open, + setModalErrorSnackMessage, +}: IAddUserContentProps) => { + const [addLoading, setAddLoading] = useState(false); + const [tags, setTags] = useState(""); + const [enabled, setEnabled] = useState(false); + + useEffect(() => { + if (lifecycle.status === "Enabled") { + setEnabled(true); + } + + if (lifecycle.tags) { + const tgs = lifecycle.tags.reduce( + (stringLab: string, currItem: any, index: number) => { + return `${stringLab}${index !== 0 ? "&" : ""}${currItem.key}=${ + currItem.value + }`; + }, + "" + ); + + setTags(tgs); + } + }, [lifecycle]); + + const saveRecord = (event: React.FormEvent) => { + event.preventDefault(); + + if (addLoading) { + return; + } + setAddLoading(true); + if (selectedBucket !== null && lifecycle !== null) { + api + .invoke( + "PUT", + `/api/v1/buckets/${selectedBucket}/lifecycle/${lifecycle.id}`, + { + disable: !enabled, + tags: tags, + } + ) + .then((res) => { + setAddLoading(false); + closeModalAndRefresh(true); + }) + .catch((err) => { + setAddLoading(false); + setModalErrorSnackMessage(err); + }); + } + }; + + return ( + { + closeModalAndRefresh(false); + }} + modalOpen={open} + title={"Edit Lifecycle Configuration"} + > +
+ { + setEnabled(e.target.checked); + }} + switchOnly + /> +
+ + +
) => { + saveRecord(e); + }} + > + + + + {}} + disabled + /> + + + { + setTags(vl); + }} + keyPlaceholder="Tag Key" + valuePlaceholder="Tag Value" + withBorder + /> + + + + + + {addLoading && ( + + + + )} + +
+
+
+ ); +}; + +const mapDispatchToProps = { + setModalErrorSnackMessage, +}; + +const connector = connect(null, mapDispatchToProps); + +export default withStyles(styles)(connector(EditLifecycleConfiguration)); diff --git a/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx b/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx index 9c605cfc3f..2a0f989b7a 100644 --- a/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx +++ b/portal-ui/src/screens/Console/Buckets/ViewBucket/ViewBucket.tsx @@ -14,7 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { useEffect, useState } from "react"; +import React, { Fragment, useEffect, useState } from "react"; +import * as reactMoment from "react-moment"; import get from "lodash/get"; import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; import Paper from "@material-ui/core/Paper"; @@ -34,6 +35,7 @@ import { BucketReplicationRule, BucketReplicationRuleDeleteMarker, BucketVersioning, + LifeCycleItem, } from "../types"; import { Button } from "@material-ui/core"; import SetAccessPolicy from "./SetAccessPolicy"; @@ -50,6 +52,10 @@ import Checkbox from "@material-ui/core/Checkbox"; import EnableBucketEncryption from "./EnableBucketEncryption"; import { connect } from "react-redux"; import { setErrorSnackMessage } from "../../../../actions"; +import EditLifecycleConfiguration from "./EditLifecycleConfiguration"; +import AddLifecycleModal from "./AddLifecycleModal"; +import { AppState } from "../../../../store"; +import { ISessionResponse } from "../../types"; const styles = (theme: Theme) => createStyles({ @@ -145,6 +151,7 @@ interface IViewBucketProps { classes: any; match: any; setErrorSnackMessage: typeof setErrorSnackMessage; + session: ISessionResponse; } interface TabPanelProps { @@ -165,7 +172,7 @@ function TabPanel(props: TabPanelProps) { style={{ marginTop: "5px" }} {...other} > - {value === index && {children}} + {value === index && {children}} ); } @@ -181,6 +188,7 @@ const ViewBucket = ({ classes, match, setErrorSnackMessage, + session, }: IViewBucketProps) => { const [info, setInfo] = useState(null); const [records, setRecords] = useState([]); @@ -203,6 +211,7 @@ const ViewBucket = ({ setEnableEncryptionScreenOpen, ] = useState(false); const [deleteOpen, setDeleteOpen] = useState(false); + const [editLifecycleOpen, setEditLifecycleOpen] = useState(false); const [selectedEvent, setSelectedEvent] = useState(null); const [bucketSize, setBucketSize] = useState("0"); const [openSetReplication, setOpenSetReplication] = useState(false); @@ -211,8 +220,12 @@ const ViewBucket = ({ const [retentionConfigOpen, setRetentionConfigOpen] = useState( false ); + const [loadingLifecycle, setLoadingLifecycle] = useState(true); + const [lifecycleRecords, setLifecycleRecords] = useState([]); + const [addLifecycleOpen, setAddLifecycleOpen] = useState(false); const bucketName = match.params["bucketName"]; + const ilmEnabled = session.features?.indexOf("ilm") > -1; useEffect(() => { if (loadingEvents) { @@ -315,6 +328,23 @@ const ViewBucket = ({ } }, [loadingEncryption, bucketName]); + useEffect(() => { + if (loadingLifecycle) { + api + .invoke("GET", `/api/v1/buckets/${bucketName}/lifecycle`) + .then((res: any) => { + const records = get(res, "lifecycle", []); + + setLifecycleRecords(records || []); + setLoadingLifecycle(false); + }) + .catch((err) => { + console.error(err); + setLoadingLifecycle(false); + }); + } + }, [loadingLifecycle, setLoadingLifecycle, bucketName]); + const loadAllBucketData = () => { setLoadingBucket(true); setLoadingSize(true); @@ -356,6 +386,13 @@ const ViewBucket = ({ } }; + const closeEditLCAndRefresh = (refresh: boolean) => { + setEditLifecycleOpen(false); + if (refresh) { + setLoadingLifecycle(true); + } + }; + const confirmDeleteEvent = (evnt: BucketEvent) => { setDeleteOpen(true); setSelectedEvent(evnt); @@ -368,25 +405,28 @@ const ViewBucket = ({ } const eventsDisplay = (events: string[]) => { - return {events.join(", ")}; + return {events.join(", ")}; }; const ruleDestDisplay = (events: BucketReplicationDestination) => { - return ( - - {events.bucket.replace("arn:aws:s3:::", "")} - - ); + return {events.bucket.replace("arn:aws:s3:::", "")}; }; const ruleDelDisplay = (events: BucketReplicationRuleDeleteMarker) => { - return {events.status}; + return null; }; const setOpenReplicationOpen = (open = false) => { setOpenSetReplication(open); }; + const closeAddLCAndRefresh = (refresh: boolean) => { + setAddLifecycleOpen(false); + if (refresh) { + setLoadingLifecycle(true); + } + }; + const handleEncryptionCheckbox = ( event: React.ChangeEvent ) => { @@ -406,8 +446,66 @@ const ViewBucket = ({ const tableActions = [{ type: "delete", onClick: confirmDeleteEvent }]; + const expirationRender = (expiration: any) => { + if (expiration.days) { + return `${expiration.days} day${expiration.days > 1 ? "s" : ""}`; + } + + if (expiration.date === "0001-01-01T00:00:00Z") { + return ""; + } + + return {expiration.date}; + }; + + const transitionRender = (transition: any) => { + if (transition.days) { + return `${transition.days} day${transition.days > 1 ? "s" : ""}`; + } + + if (transition.date === "0001-01-01T00:00:00Z") { + return ""; + } + + return {transition.date}; + }; + + const renderStorageClass = (objectST: any) => { + const stClass = get(objectST, "transition.storage_class", ""); + + return stClass; + }; + + const lifecycleColumns = [ + { label: "ID", elementKey: "id" }, + { + label: "Prefix", + elementKey: "prefix", + }, + { + label: "Status", + elementKey: "status", + }, + { + label: "Expiration", + elementKey: "expiration", + renderFunction: expirationRender, + }, + { + label: "Transition", + elementKey: "transition", + renderFunction: transitionRender, + }, + { + label: "Storage Class", + elementKey: "storage_class", + renderFunction: renderStorageClass, + renderFullObject: true, + }, + ]; + return ( - + {addScreenOpen && ( )} + {editLifecycleOpen && ( + + )} + {addLifecycleOpen && ( + + )} + ${match.params["bucketName"]}`} /> @@ -550,6 +666,7 @@ const ViewBucket = ({ > + {ilmEnabled && } @@ -579,6 +696,19 @@ const ViewBucket = ({ Add Replication Rule )} + {curTab === 2 && ( + + )} @@ -628,14 +758,29 @@ const ViewBucket = ({ idField="id" /> + + + - + ); }; -const connector = connect(null, { +const mapState = (state: AppState) => ({ + session: state.console.session, +}); + +const connector = connect(mapState, { setErrorSnackMessage, }); diff --git a/portal-ui/src/screens/Console/Buckets/types.tsx b/portal-ui/src/screens/Console/Buckets/types.tsx index fdd3349376..0e27fc2ada 100644 --- a/portal-ui/src/screens/Console/Buckets/types.tsx +++ b/portal-ui/src/screens/Console/Buckets/types.tsx @@ -114,3 +114,23 @@ export interface IRemoteBucket { status: string; service: string; } + +interface IExpirationLifecycle { + days: number; + date: string; +} + +interface ITransitionLifecycle { + days: number; + date: string; + storage_class?: string; +} + +export interface LifeCycleItem { + id: string; + prefix?: string; + expiration?: IExpirationLifecycle; + transition?: ITransitionLifecycle; + tags?: any; + status?: string; +} diff --git a/portal-ui/src/screens/Console/Common/FormComponents/QueryMultiSelector/QueryMultiSelector.tsx b/portal-ui/src/screens/Console/Common/FormComponents/QueryMultiSelector/QueryMultiSelector.tsx new file mode 100644 index 0000000000..5f16a3eda8 --- /dev/null +++ b/portal-ui/src/screens/Console/Common/FormComponents/QueryMultiSelector/QueryMultiSelector.tsx @@ -0,0 +1,251 @@ +// 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 . +import React, { + useState, + useEffect, + createRef, + useLayoutEffect, + ChangeEvent, + useRef, +} from "react"; +import get from "lodash/get"; +import debounce from "lodash/debounce"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import Grid from "@material-ui/core/Grid"; +import HelpIcon from "@material-ui/icons/Help"; +import { InputLabel, Tooltip } from "@material-ui/core"; +import { fieldBasic, tooltipHelper } from "../common/styleLibrary"; +import InputBoxWrapper from "../InputBoxWrapper/InputBoxWrapper"; +import AddIcon from "../../../../../icons/AddIcon"; + +interface IQueryMultiSelector { + elements: string; + name: string; + label: string; + tooltip?: string; + keyPlaceholder?: string; + valuePlaceholder?: string; + classes: any; + withBorder?: boolean; + onChange: (elements: string) => void; +} + +const styles = (theme: Theme) => + createStyles({ + ...fieldBasic, + ...tooltipHelper, + inputWithBorder: { + border: "1px solid #EAEAEA", + padding: 15, + height: 150, + overflowY: "auto", + position: "relative", + marginTop: 15, + }, + labelContainer: { + display: "flex", + }, + lineInputBoxes: { + display: "flex", + }, + queryDiv: { + alignSelf: "center", + margin: "0 4px", + fontWeight: 600, + }, + }); + +const QueryMultiSelector = ({ + elements, + name, + label, + tooltip = "", + keyPlaceholder = "", + valuePlaceholder = "", + onChange, + withBorder = false, + classes, +}: IQueryMultiSelector) => { + const [currentKeys, setCurrentKeys] = useState([""]); + const [currentValues, setCurrentValues] = useState([""]); + const bottomList = createRef(); + + // Use effect to get the initial values from props + useEffect(() => { + if ( + currentKeys.length === 1 && + currentKeys[0] === "" && + currentValues.length === 1 && + currentValues[0] === "" && + elements && + elements !== "" + ) { + const elementsSplit = elements.split("&"); + let keys = []; + let values = []; + + elementsSplit.forEach((element: string) => { + const splittedVals = element.split("="); + if (splittedVals.length === 2) { + keys.push(splittedVals[0]); + values.push(splittedVals[1]); + } + }); + + keys.push(""); + values.push(""); + + setCurrentKeys(keys); + setCurrentValues(values); + } + }, [currentKeys, currentValues, elements]); + + // Use effect to send new values to onChange + useEffect(() => { + const refScroll = bottomList.current; + if (refScroll) { + refScroll.scrollIntoView(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentKeys]); + + // We avoid multiple re-renders / hang issue typing too fast + const firstUpdate = useRef(true); + useLayoutEffect(() => { + if (firstUpdate.current) { + firstUpdate.current = false; + return; + } + debouncedOnChange(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentKeys, currentValues]); + + // If the last input is not empty, we add a new one + const addEmptyLine = () => { + if ( + currentKeys[currentKeys.length - 1].trim() !== "" && + currentValues[currentValues.length - 1].trim() !== "" + ) { + const keysList = [...currentKeys]; + const valuesList = [...currentValues]; + + keysList.push(""); + valuesList.push(""); + + setCurrentKeys(keysList); + setCurrentValues(valuesList); + } + }; + + // Onchange function for input box, we get the dataset-index & only update that value in the array + const onChangeKey = (e: ChangeEvent) => { + e.persist(); + + let updatedElement = [...currentKeys]; + const index = get(e.target, "dataset.index", 0); + updatedElement[index] = e.target.value; + + setCurrentKeys(updatedElement); + }; + + const onChangeValue = (e: ChangeEvent) => { + e.persist(); + + let updatedElement = [...currentValues]; + const index = get(e.target, "dataset.index", 0); + updatedElement[index] = e.target.value; + + setCurrentValues(updatedElement); + }; + + // Debounce for On Change + const debouncedOnChange = debounce(() => { + let queryString = ""; + + currentKeys.forEach((keyVal, index) => { + if (currentKeys[index] && currentValues[index]) { + let insertString = `${keyVal}=${currentValues[index]}`; + if (index !== 0) { + insertString = `&${insertString}`; + } + queryString = `${queryString}${insertString}`; + } + }); + + onChange(queryString); + }, 500); + + const inputs = currentValues.map((element, index) => { + return ( + + + : + : null} + overlayAction={() => { + addEmptyLine(); + }} + /> + + ); + }); + + return ( + + + + {label} + {tooltip !== "" && ( +
+ + + +
+ )} +
+ + {inputs} +
+ + + + ); +}; +export default withStyles(styles)(QueryMultiSelector); diff --git a/portal-ui/src/screens/Console/Common/TableWrapper/TableActionButton.tsx b/portal-ui/src/screens/Console/Common/TableWrapper/TableActionButton.tsx index 7074f7b6dd..483744b804 100644 --- a/portal-ui/src/screens/Console/Common/TableWrapper/TableActionButton.tsx +++ b/portal-ui/src/screens/Console/Common/TableWrapper/TableActionButton.tsx @@ -24,6 +24,7 @@ import DescriptionIcon from "./TableActionIcons/DescriptionIcon"; import CloudIcon from "./TableActionIcons/CloudIcon"; import ConsoleIcon from "./TableActionIcons/ConsoleIcon"; import DownloadIcon from "./TableActionIcons/DownloadIcon"; +import DisableIcon from "./TableActionIcons/DisableIcon"; import { Link } from "react-router-dom"; import { createStyles, withStyles } from "@material-ui/core/styles"; @@ -63,6 +64,8 @@ const defineIcon = (type: string, selected: boolean) => { return ; case "download": return ; + case "disable": + return ; } return null; diff --git a/portal-ui/src/screens/Console/Common/TableWrapper/TableActionIcons/DisableIcon.tsx b/portal-ui/src/screens/Console/Common/TableWrapper/TableActionIcons/DisableIcon.tsx new file mode 100644 index 0000000000..40d8ba4e45 --- /dev/null +++ b/portal-ui/src/screens/Console/Common/TableWrapper/TableActionIcons/DisableIcon.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { IIcon, selected, unSelected } from "./common"; + +const DescriptionIcon = ({ active = false }: IIcon) => { + return ( + + + + ); +}; + +export default DescriptionIcon; diff --git a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx index 93fc423a76..b339cc3d5e 100644 --- a/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx +++ b/portal-ui/src/screens/Console/Configurations/ConfigurationMain.tsx @@ -1,3 +1,19 @@ +// 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 . + import React, { Fragment, useState } from "react"; import PageHeader from "../Common/PageHeader/PageHeader"; import { Grid } from "@material-ui/core"; @@ -7,9 +23,14 @@ import Tab from "@material-ui/core/Tab"; import Tabs from "@material-ui/core/Tabs"; import ConfigurationsList from "./ConfigurationPanels/ConfigurationsList"; import ListNotificationEndpoints from "./NotificationEndpoints/ListNotificationEndpoints"; +import ListTiersConfiguration from "./TiersConfiguration/ListTiersConfiguration"; +import { AppState } from "../../../store"; +import { connect } from "react-redux"; +import { ISessionResponse } from "../types"; interface IConfigurationMain { classes: any; + session: ISessionResponse; } const styles = (theme: Theme) => @@ -23,8 +44,10 @@ const styles = (theme: Theme) => ...containerForHeader(theme.spacing(4)), }); -const ConfigurationMain = ({ classes }: IConfigurationMain) => { +const ConfigurationMain = ({ classes, session }: IConfigurationMain) => { const [selectedTab, setSelectedTab] = useState(0); + const ilmEnabled = session.features?.indexOf("ilm") > -1; + return ( @@ -44,6 +67,7 @@ const ConfigurationMain = ({ classes }: IConfigurationMain) => { > + {ilmEnabled && } {selectedTab === 0 && ( @@ -56,6 +80,11 @@ const ConfigurationMain = ({ classes }: IConfigurationMain) => { )} + {selectedTab === 2 && ( + + + + )} @@ -63,4 +92,10 @@ const ConfigurationMain = ({ classes }: IConfigurationMain) => { ); }; -export default withStyles(styles)(ConfigurationMain); +const mapState = (state: AppState) => ({ + session: state.console.session, +}); + +const connector = connect(mapState, {}); + +export default withStyles(styles)(connector(ConfigurationMain)); diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx new file mode 100644 index 0000000000..dd16858912 --- /dev/null +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/AddTierConfiguration.tsx @@ -0,0 +1,430 @@ +// 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 . + +import React, { Fragment, useEffect, useState } from "react"; +import { connect } from "react-redux"; +import Grid from "@material-ui/core/Grid"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { Button } from "@material-ui/core"; +import api from "../../../../common/api"; +import { setErrorSnackMessage } from "../../../../actions"; +import { + modalBasic, + settingsCommon, +} from "../../Common/FormComponents/common/styleLibrary"; +import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector"; + +const styles = (theme: Theme) => + createStyles({ + ...modalBasic, + ...settingsCommon, + strongText: { + fontWeight: 700, + }, + keyName: { + marginLeft: 5, + }, + buttonContainer: { + textAlign: "right", + }, + customTitle: { + ...settingsCommon.customTitle, + marginTop: 0, + }, + settingsFormContainer: { + ...settingsCommon.settingsFormContainer, + height: "calc(100vh - 422px)", + }, + }); + +interface IAddNotificationEndpointProps { + saveAndRefresh: any; + setErrorSnackMessage: typeof setErrorSnackMessage; + classes: any; +} + +const AddTierConfiguration = ({ + saveAndRefresh, + classes, + setErrorSnackMessage, +}: IAddNotificationEndpointProps) => { + //Local States + const [saving, setSaving] = useState(false); + + // Form Items + const [type, setType] = useState(""); + const [name, setName] = useState(""); + const [endpoint, setEndpoint] = useState(""); + const [bucket, setBucket] = useState(""); + const [prefix, setPrefix] = useState(""); + const [region, setRegion] = useState(""); + const [storageClass, setStorageClass] = useState(""); + + const [accessKey, setAccessKey] = useState(""); + const [secretKey, setSecretKey] = useState(""); + + const [creds, setCreds] = useState(""); + const [encodedCreds, setEncodedCreds] = useState(""); + + const [accountName, setAccountName] = useState(""); + const [accountKey, setAccountKey] = useState(""); + + // Validations + const [isFormValid, setIsFormValid] = useState(true); + + //Effects + + useEffect(() => { + if (saving) { + let request = {}; + let fields = { + name, + endpoint, + bucket, + prefix, + region, + }; + + switch (type) { + case "s3": + request = { + s3: { + ...fields, + accesskey: accessKey, + secretkey: secretKey, + storageclass: storageClass, + }, + }; + break; + case "gcs": + request = { + gcs: { + ...fields, + creds: encodedCreds, + }, + }; + break; + case "azure": + request = { + azure: { + ...fields, + accountname: accountName, + accountkey: accountKey, + }, + }; + } + + let payload = { + type, + ...request, + }; + + api + .invoke("POST", `/api/v1/admin/tiers`, payload) + .then(() => { + setSaving(false); + saveAndRefresh(); + }) + .catch((err) => { + setSaving(false); + setErrorSnackMessage(err); + }); + } + }, [ + accessKey, + accountKey, + accountName, + bucket, + encodedCreds, + endpoint, + name, + prefix, + region, + saveAndRefresh, + saving, + secretKey, + setErrorSnackMessage, + storageClass, + type, + ]); + + useEffect(() => { + let valid = true; + if (type === "") { + valid = false; + } + + if (type === "") { + valid = false; + } + if (name === "") { + valid = false; + } + if (endpoint === "") { + valid = false; + } + if (bucket === "") { + valid = false; + } + if (prefix === "") { + valid = false; + } + if (region === "") { + valid = false; + } + + if (type === "s3") { + if (accessKey === "") { + valid = false; + } + if (secretKey === "") { + valid = false; + } + } + + if (type === "gcs") { + if (encodedCreds === "") { + valid = false; + } + } + + if (type === "azure") { + if (accountName === "") { + valid = false; + } + if (accountKey === "") { + valid = false; + } + } + + setIsFormValid(valid); + }, [ + accessKey, + accountKey, + accountName, + bucket, + encodedCreds, + endpoint, + isFormValid, + name, + prefix, + region, + secretKey, + storageClass, + type, + ]); + + useEffect(() => { + switch (type) { + case "gcs": + setEndpoint("https://storage.googleapis.com/"); + break; + case "s3": + setEndpoint("https://s3.amazonaws.com"); + break; + case "azure": + setEndpoint("http://blob.core.windows.net"); + break; + } + }, [type]); + + //Fetch Actions + const submitForm = (event: React.FormEvent) => { + event.preventDefault(); + setSaving(true); + }; + + const typeSelect = (e: React.ChangeEvent<{ value: unknown }>) => { + setType(e.target.value as string); + }; + + return ( + +
+ + Add Tier Configuration + + + + + + + {type !== "" && ( + + ) => { + setName(e.target.value); + }} + /> + ) => { + setEndpoint(e.target.value); + }} + /> + {type === "s3" && ( + + ) => { + setAccessKey(e.target.value); + }} + /> + ) => { + setSecretKey(e.target.value); + }} + /> + + )} + {type === "gcs" && ( + + { + setEncodedCreds(encodedValue); + setCreds(fileName); + }} + value={creds} + /> + + )} + {type === "azure" && ( + + ) => { + setAccountName(e.target.value); + }} + /> + ) => { + setAccountKey(e.target.value); + }} + /> + + )} + ) => { + setBucket(e.target.value); + }} + /> + ) => { + setPrefix(e.target.value); + }} + /> + ) => { + setRegion(e.target.value); + }} + /> + {type === "s3" && ( + ) => { + setStorageClass(e.target.value); + }} + /> + )} + + )} + + + + + +
+
+ ); +}; + +const mapDispatchToProps = { + setErrorSnackMessage, +}; + +const connector = connect(null, mapDispatchToProps); + +export default withStyles(styles)(connector(AddTierConfiguration)); diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx new file mode 100644 index 0000000000..83a8e045d6 --- /dev/null +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx @@ -0,0 +1,330 @@ +// 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 . + +import React, { useEffect, useState, Fragment } from "react"; +import get from "lodash/get"; +import { connect } from "react-redux"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { TextField } from "@material-ui/core"; +import Grid from "@material-ui/core/Grid"; +import Button from "@material-ui/core/Button"; +import InputAdornment from "@material-ui/core/InputAdornment"; +import SearchIcon from "@material-ui/icons/Search"; +import { + actionsTray, + containerForHeader, + searchField, + settingsCommon, +} from "../../Common/FormComponents/common/styleLibrary"; +import { CreateIcon } from "../../../../icons"; +import { setErrorSnackMessage } from "../../../../actions"; +import { ITierElement, ITierResponse } from "./types"; +import api from "../../../../common/api"; +import TableWrapper from "../../Common/TableWrapper/TableWrapper"; +import SlideOptions from "../../Common/SlideOptions/SlideOptions"; +import BackSettingsIcon from "../../../../icons/BackSettingsIcon"; +import AddTierConfiguration from "./AddTierConfiguration"; +import UpdateTierCredentiasModal from "./UpdateTierCredentiasModal"; + +interface IListTiersConfig { + classes: any; + setErrorSnackMessage: typeof setErrorSnackMessage; +} + +const styles = (theme: Theme) => + createStyles({ + ...actionsTray, + ...searchField, + ...settingsCommon, + ...containerForHeader(theme.spacing(4)), + strongText: { + fontWeight: 700, + }, + keyName: { + marginLeft: 5, + }, + iconText: { + lineHeight: "24px", + }, + customConfigurationPage: { + height: "calc(100vh - 410px)", + scrollbarWidth: "none" as const, + "&::-webkit-scrollbar": { + display: "none", + }, + }, + lambdaContainer: { + padding: "15px 0", + }, + actionsTray: { + ...actionsTray.actionsTray, + padding: "0 38px", + }, + }); + +const ListTiersConfiguration = ({ + classes, + setErrorSnackMessage, +}: IListTiersConfig) => { + const [records, setRecords] = useState([]); + const [filter, setFilter] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [currentPanel, setCurrentPanel] = useState(0); + const [updateCredentialsOpen, setUpdateCredentialsOpen] = useState( + false + ); + const [selectedTier, setSelectedTier] = useState({ + type: "unsupported", + }); + + useEffect(() => { + if (isLoading) { + const fetchRecords = () => { + api + .invoke("GET", `/api/v1/admin/tiers`) + .then((res: ITierResponse) => { + setRecords(res.items || []); + setIsLoading(false); + }) + .catch((err) => { + setErrorSnackMessage(err); + setIsLoading(false); + }); + }; + fetchRecords(); + } + }, [isLoading, setErrorSnackMessage]); + + const filteredRecords = records.filter((b: ITierElement) => { + if (filter === "") { + return true; + } + const getItemName = get(b, `${b.type}.name`, ""); + const getItemType = get(b, `type`, ""); + + return getItemName.indexOf(filter) >= 0 || getItemType.indexOf(filter) >= 0; + }); + + const backClick = () => { + setCurrentPanel(currentPanel - 1); + }; + + const addTier = () => { + setCurrentPanel(1); + }; + + const tierAdded = () => { + setCurrentPanel(0); + setIsLoading(true); + }; + + const renderTierName = (item: ITierElement) => { + const name = get(item, `${item.type}.name`, ""); + + if (name !== null) { + return name; + } + + return ""; + }; + + const renderTierPrefix = (item: ITierElement) => { + const prefix = get(item, `${item.type}.prefix`, ""); + + if (prefix !== null) { + return prefix; + } + + return ""; + }; + + const renderTierEndpoint = (item: ITierElement) => { + const endpoint = get(item, `${item.type}.endpoint`, ""); + + if (endpoint !== null) { + return endpoint; + } + + return ""; + }; + + const renderTierBucket = (item: ITierElement) => { + const bucket = get(item, `${item.type}.bucket`, ""); + + if (bucket !== null) { + return bucket; + } + + return ""; + }; + + const renderTierRegion = (item: ITierElement) => { + const region = get(item, `${item.type}.region`, ""); + + if (region !== null) { + return region; + } + + return ""; + }; + + const closeTierCredentials = () => { + setUpdateCredentialsOpen(false); + }; + + return ( + + {updateCredentialsOpen && ( + + )} + + + +
+ + + Tiers + + + + + { + setFilter(event.target.value); + }} + InputProps={{ + disableUnderline: true, + startAdornment: ( + + + + ), + }} + /> + + + +
+
+ + { + setSelectedTier(tierData); + setUpdateCredentialsOpen(true); + }, + }, + ]} + columns={[ + { + label: "Tier Name", + elementKey: "type", + renderFunction: renderTierName, + renderFullObject: true, + }, + { + label: "Type", + elementKey: "type", + width: 150, + }, + { + label: "Endpoint", + elementKey: "type", + renderFunction: renderTierEndpoint, + renderFullObject: true, + }, + { + label: "Bucket", + elementKey: "type", + renderFunction: renderTierBucket, + renderFullObject: true, + }, + { + label: "Prefix", + elementKey: "type", + renderFunction: renderTierPrefix, + renderFullObject: true, + }, + { + label: "Region", + elementKey: "type", + renderFunction: renderTierRegion, + renderFullObject: true, + }, + ]} + isLoading={isLoading} + records={filteredRecords} + entityName="Tiers" + idField="service_name" + customPaperHeight={classes.customConfigurationPage} + noBackground + /> + +
+ , + + + + + + {currentPanel === 1 && ( + + )} + + , + ]} + currentSlide={currentPanel} + /> +
+
+
+
+
+ ); +}; + +const mapDispatchToProps = { + setErrorSnackMessage, +}; + +const connector = connect(null, mapDispatchToProps); + +export default withStyles(styles)(connector(ListTiersConfiguration)); diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/UpdateTierCredentiasModal.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/UpdateTierCredentiasModal.tsx new file mode 100644 index 0000000000..a9ff120fdc --- /dev/null +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/UpdateTierCredentiasModal.tsx @@ -0,0 +1,232 @@ +// 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 . + +import React, { useState, useEffect, Fragment } from "react"; +import get from "lodash/get"; +import { connect } from "react-redux"; +import { createStyles, Theme, withStyles } from "@material-ui/core/styles"; +import { Button, LinearProgress } from "@material-ui/core"; +import Grid from "@material-ui/core/Grid"; +import { modalBasic } from "../../Common/FormComponents/common/styleLibrary"; +import { setModalErrorSnackMessage } from "../../../../actions"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector"; +import api from "../../../../common/api"; +import { ITierElement } from "./types"; +import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper"; + +interface ITierCredentialsModal { + open: boolean; + closeModalAndRefresh: (refresh: boolean) => any; + classes: any; + tierData: ITierElement; + setModalErrorSnackMessage: typeof setModalErrorSnackMessage; +} + +const styles = (theme: Theme) => + createStyles({ + minTableHeader: { + color: "#393939", + "& tr": { + "& th": { + fontWeight: "bold", + }, + }, + }, + buttonContainer: { + textAlign: "right", + }, + ...modalBasic, + }); + +const UpdateTierCredentialsModal = ({ + open, + closeModalAndRefresh, + classes, + tierData, + setModalErrorSnackMessage, +}: ITierCredentialsModal) => { + const [savingTiers, setSavingTiers] = useState(false); + const [accessKey, setAccessKey] = useState(""); + const [secretKey, setSecretKey] = useState(""); + + const [creds, setCreds] = useState(""); + const [encodedCreds, setEncodedCreds] = useState(""); + + const [accountName, setAccountName] = useState(""); + const [accountKey, setAccountKey] = useState(""); + + // Validations + const [isFormValid, setIsFormValid] = useState(true); + + const type = get(tierData, "type", ""); + const name = get(tierData, `${type}.name`, ""); + + useEffect(() => { + let valid = true; + + if (type === "s3" || type === "azure") { + if (accountName === "" || accountKey === "") { + valid = false; + } + } else if (type === "gcs") { + if (encodedCreds === "") { + valid = false; + } + } + setIsFormValid(valid); + }, [accountKey, accountName, encodedCreds, type]); + + const addRecord = () => { + let rules = {}; + + if (type === "s3" || type === "azure") { + rules = { + access_key: accountName, + secret_key: accountKey, + }; + } else if (type === "gcs") { + rules = { + creds: encodedCreds, + }; + } + if (name !== "") { + api + .invoke("PUT", `/api/v1/admin/tiers/${type}/${name}/credentials`, rules) + .then(() => { + setSavingTiers(false); + closeModalAndRefresh(true); + }) + .catch((err) => { + setSavingTiers(false); + setModalErrorSnackMessage(err); + }); + } else { + setModalErrorSnackMessage( + "There was an error retrieving tier information" + ); + } + }; + + return ( + { + closeModalAndRefresh(false); + }} + title={`Update Credentials - ${type} / ${name}`} + > +
) => { + e.preventDefault(); + setSavingTiers(true); + addRecord(); + }} + > + + + {type === "s3" && ( + + ) => { + setAccessKey(e.target.value); + }} + /> + ) => { + setSecretKey(e.target.value); + }} + /> + + )} + {type === "gcs" && ( + + { + setEncodedCreds(encodedValue); + setCreds(fileName); + }} + value={creds} + /> + + )} + {type === "azure" && ( + + ) => { + setAccountName(e.target.value); + }} + /> + ) => { + setAccountKey(e.target.value); + }} + /> + + )} + + + + + {savingTiers && ( + + + + )} + +
+
+ ); +}; + +const connector = connect(null, { + setModalErrorSnackMessage, +}); + +export default withStyles(styles)(connector(UpdateTierCredentialsModal)); diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/types.ts b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/types.ts new file mode 100644 index 0000000000..9dd3519e91 --- /dev/null +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/types.ts @@ -0,0 +1,64 @@ +// 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 . + +export interface ITierS3 { + name: string; + endpoint: string; + accesskey: string; + secretkey: string; + bucket: string; + prefix: string; + region: string; + storageclass: string; +} + +export interface ITierGCS { + name: string; + endpoint: string; + creds: string; + bucket: string; + prefix: string; + region: string; + storageclass: string; +} + +export interface ITierAzure { + name: string; + endpoint: string; + accountname: string; + accountkey: string; + bucket: string; + prefix: string; + region: string; + storageclass: string; +} + +export interface ITierElement { + type: "s3" | "gcs" | "azure" | "unsupported"; + s3?: ITierS3; + gcs?: ITierGCS; + azure?: ITierAzure; +} + +export interface ITierResponse { + items: ITierElement[]; +} + +export interface ITierUpdateCreds { + access_key: string; + secret_key: string; + creds: string; +} diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantSize.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantSize.tsx index 883f3249b6..17431e9060 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantSize.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/TenantSize.tsx @@ -283,6 +283,7 @@ const TenantSize = ({ memorySize, limitSize, selectedStorageClass, + isPageValid, ]); /* End Validation of pages */ diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx index 3b1801771c..60d6002090 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx @@ -231,10 +231,6 @@ const ListTenants = ({ - - Tenants List - - }); const TenantsMain = ({ classes }: IConfigurationMain) => { - const [selectedTab, setSelectedTab] = useState(0); return ( - - Tenants Management - - { - setSelectedTab(newValue); - }} - aria-label="tenant-tabs" - > - - - - {selectedTab === 0 && ( - - - - )} - + diff --git a/portal-ui/src/screens/Console/reducer.ts b/portal-ui/src/screens/Console/reducer.ts index 6fe1e1e386..5449ff0b2f 100644 --- a/portal-ui/src/screens/Console/reducer.ts +++ b/portal-ui/src/screens/Console/reducer.ts @@ -26,6 +26,7 @@ const initialState: ConsoleState = { operator: false, status: "", pages: [], + features: [], }, }; diff --git a/portal-ui/src/screens/Console/types.ts b/portal-ui/src/screens/Console/types.ts index ca45789bb7..57d0c97ba3 100644 --- a/portal-ui/src/screens/Console/types.ts +++ b/portal-ui/src/screens/Console/types.ts @@ -17,5 +17,6 @@ export interface ISessionResponse { status: string; pages: string[]; + features: string[]; operator: boolean; } diff --git a/portal-ui/src/screens/LoginPage/LoginPage.tsx b/portal-ui/src/screens/LoginPage/LoginPage.tsx index 46ad39a405..d31e109d96 100644 --- a/portal-ui/src/screens/LoginPage/LoginPage.tsx +++ b/portal-ui/src/screens/LoginPage/LoginPage.tsx @@ -336,7 +336,7 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => { variant="h6" className={classes.headerTitle} > - Login + Welcome ); diff --git a/restapi/admin_subscription.go b/restapi/admin_subscription.go index 31b96915ae..3968682b63 100644 --- a/restapi/admin_subscription.go +++ b/restapi/admin_subscription.go @@ -130,7 +130,7 @@ func getSubscriptionActivateResponse(session *models.Principal, namespace, tenan } // If console is not deployed for this tenant return an error if minTenant.Spec.Console == nil { - return prepareError(errorGenericNotFound) + return prepareError(ErrorGenericNotFound) } // configure kubernetes client diff --git a/restapi/admin_tiers.go b/restapi/admin_tiers.go new file mode 100644 index 0000000000..6670e98b99 --- /dev/null +++ b/restapi/admin_tiers.go @@ -0,0 +1,359 @@ +// 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 . + +package restapi + +import ( + "context" + "encoding/base64" + "time" + + "github.com/minio/minio/pkg/madmin" + + "github.com/go-openapi/runtime/middleware" + "github.com/minio/console/models" + "github.com/minio/console/restapi/operations" + "github.com/minio/console/restapi/operations/admin_api" +) + +func registerAdminTiersHandlers(api *operations.ConsoleAPI) { + // return a list of notification endpoints + api.AdminAPITiersListHandler = admin_api.TiersListHandlerFunc(func(params admin_api.TiersListParams, session *models.Principal) middleware.Responder { + tierList, err := getTiersResponse(session) + if err != nil { + return admin_api.NewTiersListDefault(int(err.Code)).WithPayload(err) + } + return admin_api.NewTiersListOK().WithPayload(tierList) + }) + // add a new tiers + api.AdminAPIAddTierHandler = admin_api.AddTierHandlerFunc(func(params admin_api.AddTierParams, session *models.Principal) middleware.Responder { + err := getAddTierResponse(session, ¶ms) + if err != nil { + return admin_api.NewAddTierDefault(int(err.Code)).WithPayload(err) + } + return admin_api.NewAddTierCreated() + }) + // get a tier + api.AdminAPIGetTierHandler = admin_api.GetTierHandlerFunc(func(params admin_api.GetTierParams, session *models.Principal) middleware.Responder { + notifEndpoints, err := getGetTierResponse(session, ¶ms) + if err != nil { + return admin_api.NewGetTierDefault(int(err.Code)).WithPayload(err) + } + return admin_api.NewGetTierOK().WithPayload(notifEndpoints) + }) + // edit credentials for a tier + api.AdminAPIEditTierCredentialsHandler = admin_api.EditTierCredentialsHandlerFunc(func(params admin_api.EditTierCredentialsParams, session *models.Principal) middleware.Responder { + err := getEditTierCredentialsResponse(session, ¶ms) + if err != nil { + return admin_api.NewEditTierCredentialsDefault(int(err.Code)).WithPayload(err) + } + return admin_api.NewEditTierCredentialsOK() + }) + +} + +// getNotificationEndpoints invokes admin info and returns a list of notification endpoints +func getTiers(ctx context.Context, client MinioAdmin) (*models.TierListResponse, error) { + tiers, err := client.listTiers(ctx) + if err != nil { + return nil, err + } + + var tiersList []*models.Tier + for i := range tiers { + + switch tiers[i].Type { + case madmin.S3: + tiersList = append(tiersList, &models.Tier{ + Type: models.TierTypeS3, + S3: &models.TierS3{ + Accesskey: tiers[i].S3.AccessKey, + Bucket: tiers[i].S3.Bucket, + Endpoint: tiers[i].S3.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].S3.Prefix, + Region: tiers[i].S3.Region, + Secretkey: tiers[i].S3.SecretKey, + Storageclass: tiers[i].S3.StorageClass, + }, + }) + case madmin.GCS: + tiersList = append(tiersList, &models.Tier{ + Type: models.TierTypeGcs, + Gcs: &models.TierGcs{ + Bucket: tiers[i].GCS.Bucket, + Creds: tiers[i].GCS.Creds, + Endpoint: tiers[i].GCS.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].GCS.Prefix, + Region: tiers[i].GCS.Region, + }, + }) + case madmin.Azure: + tiersList = append(tiersList, &models.Tier{ + Type: models.TierTypeAzure, + Azure: &models.TierAzure{ + Accountkey: tiers[i].Azure.AccountKey, + Accountname: tiers[i].Azure.AccountName, + Bucket: tiers[i].Azure.Bucket, + Endpoint: tiers[i].Azure.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].Azure.Prefix, + Region: tiers[i].Azure.Region, + }, + }) + case madmin.Unsupported: + tiersList = append(tiersList, &models.Tier{ + Type: models.TierTypeUnsupported, + }) + + } + } + + // build response + return &models.TierListResponse{ + Items: tiersList, + }, nil +} + +// getTiersResponse returns a response with a list of tiers +func getTiersResponse(session *models.Principal) (*models.TierListResponse, *models.Error) { + mAdmin, err := newMAdminClient(session) + if err != nil { + return nil, prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + adminClient := adminClient{client: mAdmin} + // 20 seconds timeout + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + // serialize output + tiersResp, err := getTiers(ctx, adminClient) + if err != nil { + return nil, prepareError(err) + } + return tiersResp, nil +} + +func addTier(ctx context.Context, client MinioAdmin, params *admin_api.AddTierParams) error { + + var cfg *madmin.TierConfig + var err error + + switch params.Body.Type { + case models.TierTypeS3: + cfg, err = madmin.NewTierS3( + params.Body.S3.Name, + params.Body.S3.Accesskey, + params.Body.S3.Secretkey, + params.Body.S3.Bucket, + madmin.S3Region(params.Body.S3.Region), + madmin.S3Prefix(params.Body.S3.Prefix), + madmin.S3Endpoint(params.Body.S3.Endpoint), + madmin.S3StorageClass(params.Body.S3.Storageclass), + ) + if err != nil { + return err + } + case models.TierTypeGcs: + gcsOpts := []madmin.GCSOptions{} + prefix := params.Body.Gcs.Prefix + if prefix != "" { + gcsOpts = append(gcsOpts, madmin.GCSPrefix(prefix)) + } + + region := params.Body.Gcs.Region + if region != "" { + gcsOpts = append(gcsOpts, madmin.GCSRegion(region)) + } + base64Text := make([]byte, base64.StdEncoding.EncodedLen(len(params.Body.Gcs.Creds))) + l, _ := base64.StdEncoding.Decode(base64Text, []byte(params.Body.Gcs.Creds)) + + cfg, err = madmin.NewTierGCS( + params.Body.Gcs.Name, + base64Text[:l], + params.Body.Gcs.Bucket, + gcsOpts..., + ) + if err != nil { + return err + } + case models.TierTypeAzure: + cfg, err = madmin.NewTierAzure( + params.Body.Azure.Name, + params.Body.Azure.Accountname, + params.Body.Azure.Accountkey, + params.Body.Azure.Bucket, + madmin.AzurePrefix(params.Body.Azure.Prefix), + madmin.AzureEndpoint(params.Body.Azure.Endpoint), + madmin.AzureRegion(params.Body.Azure.Region), + ) + if err != nil { + return err + } + case models.TierTypeUnsupported: + cfg = &madmin.TierConfig{ + Type: madmin.Unsupported, + } + + } + + err = client.addTier(ctx, cfg) + if err != nil { + return err + } + return nil +} + +// getAddTierResponse returns the response of admin tier +func getAddTierResponse(session *models.Principal, params *admin_api.AddTierParams) *models.Error { + mAdmin, err := newMAdminClient(session) + if err != nil { + return prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + adminClient := adminClient{client: mAdmin} + // 20 seconds timeout + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + // serialize output + errTier := addTier(ctx, adminClient, params) + if errTier != nil { + return prepareError(errTier) + } + return nil +} + +func getTier(ctx context.Context, client MinioAdmin, params *admin_api.GetTierParams) (*models.Tier, error) { + + tiers, err := client.listTiers(ctx) + if err != nil { + return nil, err + } + for i := range tiers { + switch tiers[i].Type { + case madmin.S3: + if params.Type != models.TierTypeS3 || tiers[i].Name != params.Name { + continue + } + return &models.Tier{ + Type: models.TierTypeS3, + S3: &models.TierS3{ + Accesskey: tiers[i].S3.AccessKey, + Bucket: tiers[i].S3.Bucket, + Endpoint: tiers[i].S3.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].S3.Prefix, + Region: tiers[i].S3.Region, + Secretkey: tiers[i].S3.SecretKey, + Storageclass: tiers[i].S3.StorageClass, + }, + }, err + case madmin.GCS: + if params.Type != models.TierTypeGcs || tiers[i].Name != params.Name { + continue + } + return &models.Tier{ + Type: models.TierTypeGcs, + Gcs: &models.TierGcs{ + Bucket: tiers[i].GCS.Bucket, + Creds: tiers[i].GCS.Creds, + Endpoint: tiers[i].GCS.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].GCS.Prefix, + Region: tiers[i].GCS.Region, + }, + }, nil + case madmin.Azure: + if params.Type != models.TierTypeAzure || tiers[i].Name != params.Name { + continue + } + return &models.Tier{ + Type: models.TierTypeAzure, + Azure: &models.TierAzure{ + Accountkey: tiers[i].Azure.AccountKey, + Accountname: tiers[i].Azure.AccountName, + Bucket: tiers[i].Azure.Bucket, + Endpoint: tiers[i].Azure.Endpoint, + Name: tiers[i].Name, + Prefix: tiers[i].Azure.Prefix, + Region: tiers[i].Azure.Region, + }, + }, nil + } + } + + // build response + return nil, ErrorGenericNotFound +} + +// getGetTierResponse returns a tier +func getGetTierResponse(session *models.Principal, params *admin_api.GetTierParams) (*models.Tier, *models.Error) { + mAdmin, err := newMAdminClient(session) + if err != nil { + return nil, prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + adminClient := adminClient{client: mAdmin} + // 20 seconds timeout + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + // serialize output + addTierResp, err := getTier(ctx, adminClient, params) + if err != nil { + return nil, prepareError(err) + } + return addTierResp, nil +} + +func editTierCredentials(ctx context.Context, client MinioAdmin, params *admin_api.EditTierCredentialsParams) error { + base64Text := make([]byte, base64.StdEncoding.EncodedLen(len(params.Body.Creds))) + l, err := base64.StdEncoding.Decode(base64Text, []byte(params.Body.Creds)) + + if err != nil { + return err + } + + creds := madmin.TierCreds{ + AccessKey: params.Body.AccessKey, + SecretKey: params.Body.SecretKey, + CredsJSON: base64Text[:l], + } + return client.editTierCreds(ctx, params.Name, creds) +} + +// getEditTierCredentialsResponse returns the result of editing credentials for a tier +func getEditTierCredentialsResponse(session *models.Principal, params *admin_api.EditTierCredentialsParams) *models.Error { + mAdmin, err := newMAdminClient(session) + if err != nil { + return prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + adminClient := adminClient{client: mAdmin} + // 20 seconds timeout + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + defer cancel() + // serialize output + err = editTierCredentials(ctx, adminClient, params) + if err != nil { + return prepareError(err) + } + return nil +} diff --git a/restapi/admin_tiers_test.go b/restapi/admin_tiers_test.go new file mode 100644 index 0000000000..8c078a7ff6 --- /dev/null +++ b/restapi/admin_tiers_test.go @@ -0,0 +1,235 @@ +// 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 . + +package restapi + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/minio/console/models" + "github.com/minio/console/restapi/operations/admin_api" + "github.com/minio/minio/pkg/madmin" + "github.com/stretchr/testify/assert" +) + +// assigning mock at runtime instead of compile time +var minioListTiersMock func(ctx context.Context) ([]*madmin.TierConfig, error) + +// mock function of listTiers() +func (ac adminClientMock) listTiers(ctx context.Context) ([]*madmin.TierConfig, error) { + return minioListTiersMock(ctx) +} + +// assigning mock at runtime instead of compile time +var minioAddTiersMock func(ctx context.Context, tier *madmin.TierConfig) error + +// mock function of addTier() +func (ac adminClientMock) addTier(ctx context.Context, tier *madmin.TierConfig) error { + return minioAddTiersMock(ctx, tier) +} + +// assigning mock at runtime instead of compile time +var minioEditTiersMock func(ctx context.Context, tierName string, creds madmin.TierCreds) error + +// mock function of editTierCreds() +func (ac adminClientMock) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error { + return minioEditTiersMock(ctx, tierName, creds) +} + +func TestGetTiers(t *testing.T) { + assert := assert.New(t) + // mock minIO client + adminClient := adminClientMock{} + + function := "getTiers()" + ctx := context.Background() + + // Test-1 : getBucketLifecycle() get list of tiers + // mock lifecycle response from MinIO + returnListMock := []*madmin.TierConfig{ + { + Version: "V1", + Type: madmin.TierType(0), + Name: "S3 Tier", + S3: &madmin.TierS3{ + Endpoint: "https://s3tier.test.com/", + AccessKey: "Access Key", + SecretKey: "Secret Key", + Bucket: "buckets3", + Prefix: "pref1", + Region: "us-west-1", + StorageClass: "TT1", + }, + }, + } + + expectedOutput := &models.TierListResponse{ + Items: []*models.Tier{ + { + Type: "S3", + S3: &models.TierS3{ + Accesskey: "Access Key", + Secretkey: "Secret Key", + Bucket: "buckets3", + Endpoint: "https://s3tier.test.com/", + Name: "S3 Tier", + Prefix: "pref1", + Region: "us-west-1", + Storageclass: "TT1", + }, + }, + }, + } + + minioListTiersMock = func(ctx context.Context) ([]*madmin.TierConfig, error) { + return returnListMock, nil + } + + tiersList, err := getTiers(ctx, adminClient) + + if err != nil { + t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) + } + // verify length of tiers list is correct + assert.Equal(len(tiersList.Items), len(returnListMock), fmt.Sprintf("Failed on %s: length of lists is not the same", function)) + for i, conf := range returnListMock { + if conf.Type == madmin.TierType(0) { + // S3 + assert.Equal(expectedOutput.Items[i].S3.Name, conf.Name) + assert.Equal(expectedOutput.Items[i].S3.Bucket, conf.S3.Bucket) + assert.Equal(expectedOutput.Items[i].S3.Prefix, conf.S3.Prefix) + assert.Equal(expectedOutput.Items[i].S3.Accesskey, conf.S3.AccessKey) + assert.Equal(expectedOutput.Items[i].S3.Secretkey, conf.S3.SecretKey) + assert.Equal(expectedOutput.Items[i].S3.Endpoint, conf.S3.Endpoint) + assert.Equal(expectedOutput.Items[i].S3.Region, conf.S3.Region) + assert.Equal(expectedOutput.Items[i].S3.Storageclass, conf.S3.StorageClass) + } else if conf.Type == madmin.TierType(1) { + // Azure + assert.Equal(expectedOutput.Items[i].Azure.Name, conf.Name) + assert.Equal(expectedOutput.Items[i].Azure.Bucket, conf.Azure.Bucket) + assert.Equal(expectedOutput.Items[i].Azure.Prefix, conf.Azure.Prefix) + assert.Equal(expectedOutput.Items[i].Azure.Accountkey, conf.Azure.AccountKey) + assert.Equal(expectedOutput.Items[i].Azure.Accountname, conf.Azure.AccountName) + assert.Equal(expectedOutput.Items[i].Azure.Endpoint, conf.Azure.Endpoint) + assert.Equal(expectedOutput.Items[i].Azure.Region, conf.Azure.Region) + } else if conf.Type == madmin.TierType(2) { + // GCS + assert.Equal(expectedOutput.Items[i].Gcs.Name, conf.Name) + assert.Equal(expectedOutput.Items[i].Gcs.Bucket, conf.GCS.Bucket) + assert.Equal(expectedOutput.Items[i].Gcs.Prefix, conf.GCS.Prefix) + assert.Equal(expectedOutput.Items[i].Gcs.Creds, conf.GCS.Creds) + assert.Equal(expectedOutput.Items[i].Gcs.Endpoint, conf.GCS.Endpoint) + assert.Equal(expectedOutput.Items[i].Gcs.Region, conf.GCS.Region) + } + } + + // Test-2 : getBucketLifecycle() list is empty + returnListMockT2 := []*madmin.TierConfig{} + + minioListTiersMock = func(ctx context.Context) ([]*madmin.TierConfig, error) { + return returnListMockT2, nil + } + + tiersListT2, err := getTiers(ctx, adminClient) + + if err != nil { + t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) + } + + if len(tiersListT2.Items) != 0 { + t.Errorf("Failed on %s:, returned list was not empty", function) + } +} + +func TestAddTier(t *testing.T) { + assert := assert.New(t) + // mock minIO client + adminClient := adminClientMock{} + + function := "addTier()" + ctx := context.Background() + + // Test-1: addTier() add new Tier + minioAddTiersMock = func(ctx context.Context, tier *madmin.TierConfig) error { + return nil + } + + paramsToAdd := admin_api.AddTierParams{ + Body: &models.Tier{ + Type: "S3", + S3: &models.TierS3{ + Accesskey: "TestAK", + Bucket: "bucket1", + Endpoint: "https://test.com/", + Name: "TIERS3", + Prefix: "Pr1", + Region: "us-west-1", + Secretkey: "SecretK", + Storageclass: "STCLASS", + }, + }, + } + + err := addTier(ctx, adminClient, ¶msToAdd) + assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function)) + + // Test-2: addTier() error adding Tier + minioAddTiersMock = func(ctx context.Context, tier *madmin.TierConfig) error { + return errors.New("error setting new tier") + } + + err2 := addTier(ctx, adminClient, ¶msToAdd) + + assert.Equal(errors.New("error setting new tier"), err2, fmt.Sprintf("Failed on %s: Error returned", function)) +} + +func TestUpdateTierCreds(t *testing.T) { + assert := assert.New(t) + // mock minIO client + adminClient := adminClientMock{} + + function := "editTierCredentials()" + ctx := context.Background() + + // Test-1: editTierCredentials() update Tier configuration + minioEditTiersMock = func(ctx context.Context, tierName string, creds madmin.TierCreds) error { + return nil + } + + params := &admin_api.EditTierCredentialsParams{ + Name: "TESTTIER", + Body: &models.TierCredentialsRequest{ + AccessKey: "New Key", + SecretKey: "Secret Key", + }, + } + + err := editTierCredentials(ctx, adminClient, params) + + assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function)) + + // Test-2: editTierCredentials() update Tier configuration failure + minioEditTiersMock = func(ctx context.Context, tierName string, creds madmin.TierCreds) error { + return errors.New("error message") + } + + errT2 := editTierCredentials(ctx, adminClient, params) + + assert.Equal(errors.New("error message"), errT2, fmt.Sprintf("Failed on %s: Error returned", function)) +} diff --git a/restapi/client-admin.go b/restapi/client-admin.go index b958fbe251..68262a5de0 100644 --- a/restapi/client-admin.go +++ b/restapi/client-admin.go @@ -105,6 +105,12 @@ type MinioAdmin interface { changePassword(ctx context.Context, accessKey, secretKey string) error serverHealthInfo(ctx context.Context, healthDataTypes []madmin.HealthDataType, deadline time.Duration) <-chan madmin.HealthInfo + // List Tiers + listTiers(ctx context.Context) ([]*madmin.TierConfig, error) + // Add Tier + addTier(ctx context.Context, tier *madmin.TierConfig) error + // Edit Tier Credentials + editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error } // Interface implementation @@ -295,6 +301,21 @@ func (ac adminClient) serverHealthInfo(ctx context.Context, healthDataTypes []ma return ac.client.ServerHealthInfo(ctx, healthDataTypes, deadline) } +// implements madmin.listTiers() +func (ac adminClient) listTiers(ctx context.Context) ([]*madmin.TierConfig, error) { + return ac.client.ListTiers(ctx) +} + +// implements madmin.AddTier() +func (ac adminClient) addTier(ctx context.Context, cfg *madmin.TierConfig) error { + return ac.client.AddTier(ctx, cfg) +} + +// implements madmin.EditTier() +func (ac adminClient) editTierCreds(ctx context.Context, tierName string, creds madmin.TierCreds) error { + return ac.client.EditTier(ctx, tierName, creds) +} + func newMAdminClient(sessionClaims *models.Principal) (*madmin.AdminClient, error) { adminClient, err := newAdminFromClaims(sessionClaims) if err != nil { diff --git a/restapi/client.go b/restapi/client.go index f3fdd079bf..a8f83e5099 100644 --- a/restapi/client.go +++ b/restapi/client.go @@ -38,6 +38,7 @@ import ( "github.com/minio/mc/pkg/probe" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" + "github.com/minio/minio-go/v7/pkg/lifecycle" "github.com/minio/minio-go/v7/pkg/notification" "github.com/minio/minio-go/v7/pkg/tags" ) @@ -71,6 +72,8 @@ type MinioClient interface { getObjectTagging(ctx context.Context, bucketName, objectName string, opts minio.GetObjectTaggingOptions) (*tags.Tags, error) setObjectLockConfig(ctx context.Context, bucketName string, mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit) error getBucketObjectLockConfig(ctx context.Context, bucketName string) (mode *minio.RetentionMode, validity *uint, unit *minio.ValidityUnit, err error) + getLifecycleRules(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) + setBucketLifecycle(ctx context.Context, bucketName string, config *lifecycle.Configuration) error } // Interface implementation @@ -180,6 +183,13 @@ func (c minioClient) getBucketObjectLockConfig(ctx context.Context, bucketName s return c.client.GetBucketObjectLockConfig(ctx, bucketName) } +func (c minioClient) getLifecycleRules(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return c.client.GetBucketLifecycle(ctx, bucketName) +} +func (c minioClient) setBucketLifecycle(ctx context.Context, bucketName string, config *lifecycle.Configuration) error { + return c.client.SetBucketLifecycle(ctx, bucketName, config) +} + // MCClient interface with all functions to be implemented // by mock when testing, it should include all mc/S3Client respective api calls // that are used within this project. diff --git a/restapi/configure_console.go b/restapi/configure_console.go index 34649f5335..3f4894a7cb 100644 --- a/restapi/configure_console.go +++ b/restapi/configure_console.go @@ -104,6 +104,8 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler { registerConfigHandlers(api) // Register bucket events handlers registerBucketEventsHandlers(api) + // Register bucket lifecycle handlers + registerBucketsLifecycleHandlers(api) // Register service handlers registerServiceHandlers(api) // Register profiling handlers @@ -124,6 +126,8 @@ func configureAPI(api *operations.ConsoleAPI) http.Handler { registerLogSearchHandlers(api) // Register admin subscription handlers registerSubscriptionHandlers(api) + // Register Account handlers + registerAdminTiersHandlers(api) // Operator Console // Register tenant handlers diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index f633596d83..bb89de7e97 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -203,6 +203,146 @@ func init() { } } }, + "/admin/tiers": { + "get": { + "tags": [ + "AdminAPI" + ], + "summary": "Returns a list of tiers for ilm", + "operationId": "TiersList", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/tierListResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, + "post": { + "tags": [ + "AdminAPI" + ], + "summary": "Allows to configure a new tier", + "operationId": "AddTier", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tier" + } + } + ], + "responses": { + "201": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/admin/tiers/{type}/{name}": { + "get": { + "tags": [ + "AdminAPI" + ], + "summary": "Get Tier", + "operationId": "GetTier", + "parameters": [ + { + "enum": [ + "s3", + "gcs", + "azure" + ], + "type": "string", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/tier" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/admin/tiers/{type}/{name}/credentials": { + "put": { + "tags": [ + "AdminAPI" + ], + "summary": "Edit Tier Credentials", + "operationId": "EditTierCredentials", + "parameters": [ + { + "enum": [ + "s3", + "gcs", + "azure" + ], + "type": "string", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tierCredentialsRequest" + } + } + ], + "responses": { + "200": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/buckets": { "get": { "tags": [ @@ -487,6 +627,113 @@ func init() { } } }, + "/buckets/{bucket_name}/lifecycle": { + "get": { + "tags": [ + "UserAPI" + ], + "summary": "Bucket Lifecycle", + "operationId": "GetBucketLifecycle", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/bucketLifecycleResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, + "post": { + "tags": [ + "UserAPI" + ], + "summary": "Add Bucket Lifecycle", + "operationId": "AddBucketLifecycle", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/addBucketLifecycle" + } + } + ], + "responses": { + "201": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/buckets/{bucket_name}/lifecycle/{lifecycle_id}": { + "put": { + "tags": [ + "UserAPI" + ], + "summary": "Update Lifecycle rule", + "operationId": "UpdateBucketLifecycle", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "lifecycle_id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/updateBucketLifecycle" + } + } + ], + "responses": { + "200": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/buckets/{bucket_name}/objects": { "get": { "tags": [ @@ -3117,6 +3364,67 @@ func init() { } } }, + "addBucketLifecycle": { + "type": "object", + "properties": { + "disable": { + "description": "Non required, toggle to disable or enable rule", + "type": "boolean" + }, + "expired_object_delete_marker": { + "description": "Non required, toggle to disable or enable rule", + "type": "boolean" + }, + "expiry_date": { + "description": "Required in case of expiry_days or transition fields are not set. it defines an expiry date for ILM", + "type": "string" + }, + "expiry_days": { + "description": "Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_expiration_days": { + "description": "Non required, can be set in case of expiration is enabled", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_transition_days": { + "description": "Non required, can be set in case of transition is enabled", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_transition_storage_class": { + "description": "Non required, can be set in case of transition is enabled", + "type": "string" + }, + "prefix": { + "description": "Non required field, it matches a prefix to perform ILM operations on it", + "type": "string" + }, + "storage_class": { + "description": "Required only in case of transition is set. it refers to a tier", + "type": "string" + }, + "tags": { + "description": "Non required field, tags to match ILM files", + "type": "string" + }, + "transition_date": { + "description": "Required in case of transition_days or expiry fields are not set. it defines a transition date for ILM", + "type": "string" + }, + "transition_days": { + "description": "Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM", + "type": "integer", + "format": "int32", + "default": 0 + } + } + }, "addBucketReplication": { "type": "object", "properties": { @@ -3334,6 +3642,17 @@ func init() { } } }, + "bucketLifecycleResponse": { + "type": "object", + "properties": { + "lifecycle": { + "type": "array", + "items": { + "$ref": "#/definitions/objectBucketLifecycle" + } + } + } + }, "bucketObject": { "type": "object", "properties": { @@ -3726,14 +4045,29 @@ func init() { } } }, - "gcpConfiguration": { + "expirationResponse": { "type": "object", - "required": [ - "secretmanager" - ], "properties": { - "secretmanager": { - "type": "object", + "date": { + "type": "string" + }, + "days": { + "type": "integer", + "format": "int64" + }, + "delete_marker": { + "type": "boolean" + } + } + }, + "gcpConfiguration": { + "type": "object", + "required": [ + "secretmanager" + ], + "properties": { + "secretmanager": { + "type": "object", "required": [ "project_id" ], @@ -3969,6 +4303,17 @@ func init() { } } }, + "lifecycleTag": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "listBucketEventsResponse": { "type": "object", "properties": { @@ -4430,6 +4775,32 @@ func init() { "get" ] }, + "objectBucketLifecycle": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/expirationResponse" + }, + "id": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "status": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/definitions/lifecycleTag" + } + }, + "transition": { + "$ref": "#/definitions/transitionResponse" + } + } + }, "objectLegalHoldStatus": { "type": "string", "enum": [ @@ -5023,6 +5394,12 @@ func init() { "sessionResponse": { "type": "object", "properties": { + "features": { + "type": "array", + "items": { + "type": "string" + } + }, "operator": { "type": "boolean" }, @@ -5307,6 +5684,136 @@ func init() { } } }, + "tier": { + "type": "object", + "properties": { + "azure": { + "type": "object", + "$ref": "#/definitions/tier_azure" + }, + "gcs": { + "type": "object", + "$ref": "#/definitions/tier_gcs" + }, + "s3": { + "type": "object", + "$ref": "#/definitions/tier_s3" + }, + "type": { + "type": "string", + "enum": [ + "s3", + "gcs", + "azure", + "unsupported" + ] + } + } + }, + "tierCredentialsRequest": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "creds": { + "description": "a base64 encoded value", + "type": "string" + }, + "secret_key": { + "type": "string" + } + } + }, + "tierListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/tier" + } + } + } + }, + "tier_azure": { + "type": "object", + "properties": { + "accountkey": { + "type": "string" + }, + "accountname": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + } + } + }, + "tier_gcs": { + "type": "object", + "properties": { + "bucket": { + "type": "string" + }, + "creds": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + } + } + }, + "tier_s3": { + "type": "object", + "properties": { + "accesskey": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + }, + "secretkey": { + "type": "string" + }, + "storageclass": { + "type": "string" + } + } + }, "tlsConfiguration": { "type": "object", "properties": { @@ -5328,6 +5835,32 @@ func init() { } } }, + "transitionResponse": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "days": { + "type": "integer", + "format": "int64" + }, + "storage_class": { + "type": "string" + } + } + }, + "updateBucketLifecycle": { + "type": "object", + "properties": { + "disable": { + "type": "boolean" + }, + "tags": { + "type": "string" + } + } + }, "updateGroupRequest": { "type": "object", "required": [ @@ -5718,6 +6251,146 @@ func init() { } } }, + "/admin/tiers": { + "get": { + "tags": [ + "AdminAPI" + ], + "summary": "Returns a list of tiers for ilm", + "operationId": "TiersList", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/tierListResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, + "post": { + "tags": [ + "AdminAPI" + ], + "summary": "Allows to configure a new tier", + "operationId": "AddTier", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tier" + } + } + ], + "responses": { + "201": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/admin/tiers/{type}/{name}": { + "get": { + "tags": [ + "AdminAPI" + ], + "summary": "Get Tier", + "operationId": "GetTier", + "parameters": [ + { + "enum": [ + "s3", + "gcs", + "azure" + ], + "type": "string", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/tier" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/admin/tiers/{type}/{name}/credentials": { + "put": { + "tags": [ + "AdminAPI" + ], + "summary": "Edit Tier Credentials", + "operationId": "EditTierCredentials", + "parameters": [ + { + "enum": [ + "s3", + "gcs", + "azure" + ], + "type": "string", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/tierCredentialsRequest" + } + } + ], + "responses": { + "200": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, "/buckets": { "get": { "tags": [ @@ -5862,17 +6535,136 @@ func init() { "parameters": [ { "type": "string", - "name": "bucket_name", + "name": "bucket_name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/bucketEncryptionInfo" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/buckets/{bucket_name}/events": { + "get": { + "tags": [ + "UserAPI" + ], + "summary": "List Bucket Events", + "operationId": "ListBucketEvents", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "int32", + "name": "offset", + "in": "query" + }, + { + "type": "integer", + "format": "int32", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/listBucketEventsResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, + "post": { + "tags": [ + "UserAPI" + ], + "summary": "Create Bucket Event", + "operationId": "CreateBucketEvent", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/bucketEventRequest" + } + } + ], + "responses": { + "201": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + } + }, + "/buckets/{bucket_name}/events/{arn}": { + "delete": { + "tags": [ + "UserAPI" + ], + "summary": "Delete Bucket Event", + "operationId": "DeleteBucketEvent", + "parameters": [ + { + "type": "string", + "name": "bucket_name", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "arn", "in": "path", "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/notificationDeleteRequest" + } } ], "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/bucketEncryptionInfo" - } + "204": { + "description": "A successful response." }, "default": { "description": "Generic error response.", @@ -5883,38 +6675,26 @@ func init() { } } }, - "/buckets/{bucket_name}/events": { + "/buckets/{bucket_name}/lifecycle": { "get": { "tags": [ "UserAPI" ], - "summary": "List Bucket Events", - "operationId": "ListBucketEvents", + "summary": "Bucket Lifecycle", + "operationId": "GetBucketLifecycle", "parameters": [ { "type": "string", "name": "bucket_name", "in": "path", "required": true - }, - { - "type": "integer", - "format": "int32", - "name": "offset", - "in": "query" - }, - { - "type": "integer", - "format": "int32", - "name": "limit", - "in": "query" } ], "responses": { "200": { "description": "A successful response.", "schema": { - "$ref": "#/definitions/listBucketEventsResponse" + "$ref": "#/definitions/bucketLifecycleResponse" } }, "default": { @@ -5929,8 +6709,8 @@ func init() { "tags": [ "UserAPI" ], - "summary": "Create Bucket Event", - "operationId": "CreateBucketEvent", + "summary": "Add Bucket Lifecycle", + "operationId": "AddBucketLifecycle", "parameters": [ { "type": "string", @@ -5943,7 +6723,7 @@ func init() { "in": "body", "required": true, "schema": { - "$ref": "#/definitions/bucketEventRequest" + "$ref": "#/definitions/addBucketLifecycle" } } ], @@ -5960,13 +6740,13 @@ func init() { } } }, - "/buckets/{bucket_name}/events/{arn}": { - "delete": { + "/buckets/{bucket_name}/lifecycle/{lifecycle_id}": { + "put": { "tags": [ "UserAPI" ], - "summary": "Delete Bucket Event", - "operationId": "DeleteBucketEvent", + "summary": "Update Lifecycle rule", + "operationId": "UpdateBucketLifecycle", "parameters": [ { "type": "string", @@ -5976,7 +6756,7 @@ func init() { }, { "type": "string", - "name": "arn", + "name": "lifecycle_id", "in": "path", "required": true }, @@ -5985,12 +6765,12 @@ func init() { "in": "body", "required": true, "schema": { - "$ref": "#/definitions/notificationDeleteRequest" + "$ref": "#/definitions/updateBucketLifecycle" } } ], "responses": { - "204": { + "200": { "description": "A successful response." }, "default": { @@ -9241,6 +10021,67 @@ func init() { } } }, + "addBucketLifecycle": { + "type": "object", + "properties": { + "disable": { + "description": "Non required, toggle to disable or enable rule", + "type": "boolean" + }, + "expired_object_delete_marker": { + "description": "Non required, toggle to disable or enable rule", + "type": "boolean" + }, + "expiry_date": { + "description": "Required in case of expiry_days or transition fields are not set. it defines an expiry date for ILM", + "type": "string" + }, + "expiry_days": { + "description": "Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_expiration_days": { + "description": "Non required, can be set in case of expiration is enabled", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_transition_days": { + "description": "Non required, can be set in case of transition is enabled", + "type": "integer", + "format": "int32", + "default": 0 + }, + "noncurrentversion_transition_storage_class": { + "description": "Non required, can be set in case of transition is enabled", + "type": "string" + }, + "prefix": { + "description": "Non required field, it matches a prefix to perform ILM operations on it", + "type": "string" + }, + "storage_class": { + "description": "Required only in case of transition is set. it refers to a tier", + "type": "string" + }, + "tags": { + "description": "Non required field, tags to match ILM files", + "type": "string" + }, + "transition_date": { + "description": "Required in case of transition_days or expiry fields are not set. it defines a transition date for ILM", + "type": "string" + }, + "transition_days": { + "description": "Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM", + "type": "integer", + "format": "int32", + "default": 0 + } + } + }, "addBucketReplication": { "type": "object", "properties": { @@ -9458,6 +10299,17 @@ func init() { } } }, + "bucketLifecycleResponse": { + "type": "object", + "properties": { + "lifecycle": { + "type": "array", + "items": { + "$ref": "#/definitions/objectBucketLifecycle" + } + } + } + }, "bucketObject": { "type": "object", "properties": { @@ -9850,6 +10702,21 @@ func init() { } } }, + "expirationResponse": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "days": { + "type": "integer", + "format": "int64" + }, + "delete_marker": { + "type": "boolean" + } + } + }, "gcpConfiguration": { "type": "object", "required": [ @@ -10093,6 +10960,17 @@ func init() { } } }, + "lifecycleTag": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, "listBucketEventsResponse": { "type": "object", "properties": { @@ -10510,6 +11388,32 @@ func init() { "get" ] }, + "objectBucketLifecycle": { + "type": "object", + "properties": { + "expiration": { + "$ref": "#/definitions/expirationResponse" + }, + "id": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "status": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "$ref": "#/definitions/lifecycleTag" + } + }, + "transition": { + "$ref": "#/definitions/transitionResponse" + } + } + }, "objectLegalHoldStatus": { "type": "string", "enum": [ @@ -11012,6 +11916,12 @@ func init() { "sessionResponse": { "type": "object", "properties": { + "features": { + "type": "array", + "items": { + "type": "string" + } + }, "operator": { "type": "boolean" }, @@ -11296,6 +12206,136 @@ func init() { } } }, + "tier": { + "type": "object", + "properties": { + "azure": { + "type": "object", + "$ref": "#/definitions/tier_azure" + }, + "gcs": { + "type": "object", + "$ref": "#/definitions/tier_gcs" + }, + "s3": { + "type": "object", + "$ref": "#/definitions/tier_s3" + }, + "type": { + "type": "string", + "enum": [ + "s3", + "gcs", + "azure", + "unsupported" + ] + } + } + }, + "tierCredentialsRequest": { + "type": "object", + "properties": { + "access_key": { + "type": "string" + }, + "creds": { + "description": "a base64 encoded value", + "type": "string" + }, + "secret_key": { + "type": "string" + } + } + }, + "tierListResponse": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/tier" + } + } + } + }, + "tier_azure": { + "type": "object", + "properties": { + "accountkey": { + "type": "string" + }, + "accountname": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + } + } + }, + "tier_gcs": { + "type": "object", + "properties": { + "bucket": { + "type": "string" + }, + "creds": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + } + } + }, + "tier_s3": { + "type": "object", + "properties": { + "accesskey": { + "type": "string" + }, + "bucket": { + "type": "string" + }, + "endpoint": { + "type": "string" + }, + "name": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "region": { + "type": "string" + }, + "secretkey": { + "type": "string" + }, + "storageclass": { + "type": "string" + } + } + }, "tlsConfiguration": { "type": "object", "properties": { @@ -11317,6 +12357,32 @@ func init() { } } }, + "transitionResponse": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "days": { + "type": "integer", + "format": "int64" + }, + "storage_class": { + "type": "string" + } + } + }, + "updateBucketLifecycle": { + "type": "object", + "properties": { + "disable": { + "type": "boolean" + }, + "tags": { + "type": "string" + } + } + }, "updateGroupRequest": { "type": "object", "required": [ diff --git a/restapi/error.go b/restapi/error.go index c5d275ab1b..28fd4841f2 100644 --- a/restapi/error.go +++ b/restapi/error.go @@ -17,7 +17,8 @@ var ( errorGenericInvalidSession = errors.New("invalid session") errorGenericUnauthorized = errors.New("unauthorized") errorGenericForbidden = errors.New("forbidden") - errorGenericNotFound = errors.New("not found") + // ErrorGenericNotFound Generic error for not found + ErrorGenericNotFound = errors.New("not found") // Explicit error messages errorInvalidErasureCodingValue = errors.New("invalid Erasure Coding Value") errorUnableToGetTenantUsage = errors.New("unable to get tenant usage") @@ -53,7 +54,11 @@ func prepareError(err ...error) *models.Error { } if k8sErrors.IsNotFound(err[0]) { errorCode = 404 - errorMessage = errorGenericNotFound.Error() + errorMessage = ErrorGenericNotFound.Error() + } + if err[0] == ErrorGenericNotFound { + errorCode = 404 + errorMessage = ErrorGenericNotFound.Error() } if errors.Is(err[0], errInvalidCredentials) { errorCode = 401 @@ -128,6 +133,11 @@ func prepareError(err ...error) *models.Error { if len(err) > 2 && err[2] != nil { log.Print("debugging error: ", err[2].Error()) } + + errRemoteTierExists := errors.New("Specified remote tier already exists") //nolint + if errors.Is(err[0], errRemoteTierExists) { + errorMessage = err[0].Error() + } } return &models.Error{Code: errorCode, Message: swag.String(errorMessage)} } diff --git a/restapi/operations/admin_api/add_tier.go b/restapi/operations/admin_api/add_tier.go new file mode 100644 index 0000000000..85a2845ab8 --- /dev/null +++ b/restapi/operations/admin_api/add_tier.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// AddTierHandlerFunc turns a function with the right signature into a add tier handler +type AddTierHandlerFunc func(AddTierParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn AddTierHandlerFunc) Handle(params AddTierParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// AddTierHandler interface for that can handle valid add tier params +type AddTierHandler interface { + Handle(AddTierParams, *models.Principal) middleware.Responder +} + +// NewAddTier creates a new http.Handler for the add tier operation +func NewAddTier(ctx *middleware.Context, handler AddTierHandler) *AddTier { + return &AddTier{Context: ctx, Handler: handler} +} + +/*AddTier swagger:route POST /admin/tiers AdminAPI addTier + +Allows to configure a new tier + +*/ +type AddTier struct { + Context *middleware.Context + Handler AddTierHandler +} + +func (o *AddTier) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewAddTierParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/admin_api/add_tier_parameters.go b/restapi/operations/admin_api/add_tier_parameters.go new file mode 100644 index 0000000000..a9cb741dcc --- /dev/null +++ b/restapi/operations/admin_api/add_tier_parameters.go @@ -0,0 +1,94 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// NewAddTierParams creates a new AddTierParams object +// no default values defined in spec. +func NewAddTierParams() AddTierParams { + + return AddTierParams{} +} + +// AddTierParams contains all the bound params for the add tier operation +// typically these are obtained from a http.Request +// +// swagger:parameters AddTier +type AddTierParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: body + */ + Body *models.Tier +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewAddTierParams() beforehand. +func (o *AddTierParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.Tier + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("body", "body", "")) + } else { + res = append(res, errors.NewParseError("body", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Body = &body + } + } + } else { + res = append(res, errors.Required("body", "body", "")) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/restapi/operations/admin_api/add_tier_responses.go b/restapi/operations/admin_api/add_tier_responses.go new file mode 100644 index 0000000000..7d8edac973 --- /dev/null +++ b/restapi/operations/admin_api/add_tier_responses.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// AddTierCreatedCode is the HTTP code returned for type AddTierCreated +const AddTierCreatedCode int = 201 + +/*AddTierCreated A successful response. + +swagger:response addTierCreated +*/ +type AddTierCreated struct { +} + +// NewAddTierCreated creates AddTierCreated with default headers values +func NewAddTierCreated() *AddTierCreated { + + return &AddTierCreated{} +} + +// WriteResponse to the client +func (o *AddTierCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(201) +} + +/*AddTierDefault Generic error response. + +swagger:response addTierDefault +*/ +type AddTierDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewAddTierDefault creates AddTierDefault with default headers values +func NewAddTierDefault(code int) *AddTierDefault { + if code <= 0 { + code = 500 + } + + return &AddTierDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the add tier default response +func (o *AddTierDefault) WithStatusCode(code int) *AddTierDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the add tier default response +func (o *AddTierDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the add tier default response +func (o *AddTierDefault) WithPayload(payload *models.Error) *AddTierDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the add tier default response +func (o *AddTierDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AddTierDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/admin_api/add_tier_urlbuilder.go b/restapi/operations/admin_api/add_tier_urlbuilder.go new file mode 100644 index 0000000000..73cfe63566 --- /dev/null +++ b/restapi/operations/admin_api/add_tier_urlbuilder.go @@ -0,0 +1,104 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// AddTierURL generates an URL for the add tier operation +type AddTierURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AddTierURL) WithBasePath(bp string) *AddTierURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AddTierURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *AddTierURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/admin/tiers" + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *AddTierURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *AddTierURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *AddTierURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on AddTierURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on AddTierURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *AddTierURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/admin_api/edit_tier_credentials.go b/restapi/operations/admin_api/edit_tier_credentials.go new file mode 100644 index 0000000000..c9ecfff05f --- /dev/null +++ b/restapi/operations/admin_api/edit_tier_credentials.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// EditTierCredentialsHandlerFunc turns a function with the right signature into a edit tier credentials handler +type EditTierCredentialsHandlerFunc func(EditTierCredentialsParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn EditTierCredentialsHandlerFunc) Handle(params EditTierCredentialsParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// EditTierCredentialsHandler interface for that can handle valid edit tier credentials params +type EditTierCredentialsHandler interface { + Handle(EditTierCredentialsParams, *models.Principal) middleware.Responder +} + +// NewEditTierCredentials creates a new http.Handler for the edit tier credentials operation +func NewEditTierCredentials(ctx *middleware.Context, handler EditTierCredentialsHandler) *EditTierCredentials { + return &EditTierCredentials{Context: ctx, Handler: handler} +} + +/*EditTierCredentials swagger:route PUT /admin/tiers/{type}/{name}/credentials AdminAPI editTierCredentials + +Edit Tier Credentials + +*/ +type EditTierCredentials struct { + Context *middleware.Context + Handler EditTierCredentialsHandler +} + +func (o *EditTierCredentials) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewEditTierCredentialsParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/admin_api/edit_tier_credentials_parameters.go b/restapi/operations/admin_api/edit_tier_credentials_parameters.go new file mode 100644 index 0000000000..b171aee706 --- /dev/null +++ b/restapi/operations/admin_api/edit_tier_credentials_parameters.go @@ -0,0 +1,160 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" + + "github.com/minio/console/models" +) + +// NewEditTierCredentialsParams creates a new EditTierCredentialsParams object +// no default values defined in spec. +func NewEditTierCredentialsParams() EditTierCredentialsParams { + + return EditTierCredentialsParams{} +} + +// EditTierCredentialsParams contains all the bound params for the edit tier credentials operation +// typically these are obtained from a http.Request +// +// swagger:parameters EditTierCredentials +type EditTierCredentialsParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: body + */ + Body *models.TierCredentialsRequest + /* + Required: true + In: path + */ + Name string + /* + Required: true + In: path + */ + Type string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewEditTierCredentialsParams() beforehand. +func (o *EditTierCredentialsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.TierCredentialsRequest + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("body", "body", "")) + } else { + res = append(res, errors.NewParseError("body", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Body = &body + } + } + } else { + res = append(res, errors.Required("body", "body", "")) + } + rName, rhkName, _ := route.Params.GetOK("name") + if err := o.bindName(rName, rhkName, route.Formats); err != nil { + res = append(res, err) + } + + rType, rhkType, _ := route.Params.GetOK("type") + if err := o.bindType(rType, rhkType, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindName binds and validates parameter Name from path. +func (o *EditTierCredentialsParams) bindName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.Name = raw + + return nil +} + +// bindType binds and validates parameter Type from path. +func (o *EditTierCredentialsParams) bindType(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.Type = raw + + if err := o.validateType(formats); err != nil { + return err + } + + return nil +} + +// validateType carries on validations for parameter Type +func (o *EditTierCredentialsParams) validateType(formats strfmt.Registry) error { + + if err := validate.EnumCase("type", "path", o.Type, []interface{}{"s3", "gcs", "azure"}, true); err != nil { + return err + } + + return nil +} diff --git a/restapi/operations/admin_api/edit_tier_credentials_responses.go b/restapi/operations/admin_api/edit_tier_credentials_responses.go new file mode 100644 index 0000000000..d8e6627592 --- /dev/null +++ b/restapi/operations/admin_api/edit_tier_credentials_responses.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// EditTierCredentialsOKCode is the HTTP code returned for type EditTierCredentialsOK +const EditTierCredentialsOKCode int = 200 + +/*EditTierCredentialsOK A successful response. + +swagger:response editTierCredentialsOK +*/ +type EditTierCredentialsOK struct { +} + +// NewEditTierCredentialsOK creates EditTierCredentialsOK with default headers values +func NewEditTierCredentialsOK() *EditTierCredentialsOK { + + return &EditTierCredentialsOK{} +} + +// WriteResponse to the client +func (o *EditTierCredentialsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(200) +} + +/*EditTierCredentialsDefault Generic error response. + +swagger:response editTierCredentialsDefault +*/ +type EditTierCredentialsDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewEditTierCredentialsDefault creates EditTierCredentialsDefault with default headers values +func NewEditTierCredentialsDefault(code int) *EditTierCredentialsDefault { + if code <= 0 { + code = 500 + } + + return &EditTierCredentialsDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the edit tier credentials default response +func (o *EditTierCredentialsDefault) WithStatusCode(code int) *EditTierCredentialsDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the edit tier credentials default response +func (o *EditTierCredentialsDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the edit tier credentials default response +func (o *EditTierCredentialsDefault) WithPayload(payload *models.Error) *EditTierCredentialsDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the edit tier credentials default response +func (o *EditTierCredentialsDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *EditTierCredentialsDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/admin_api/edit_tier_credentials_urlbuilder.go b/restapi/operations/admin_api/edit_tier_credentials_urlbuilder.go new file mode 100644 index 0000000000..27f813509e --- /dev/null +++ b/restapi/operations/admin_api/edit_tier_credentials_urlbuilder.go @@ -0,0 +1,124 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// EditTierCredentialsURL generates an URL for the edit tier credentials operation +type EditTierCredentialsURL struct { + Name string + Type string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *EditTierCredentialsURL) WithBasePath(bp string) *EditTierCredentialsURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *EditTierCredentialsURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *EditTierCredentialsURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/admin/tiers/{type}/{name}/credentials" + + name := o.Name + if name != "" { + _path = strings.Replace(_path, "{name}", name, -1) + } else { + return nil, errors.New("name is required on EditTierCredentialsURL") + } + + typeVar := o.Type + if typeVar != "" { + _path = strings.Replace(_path, "{type}", typeVar, -1) + } else { + return nil, errors.New("type is required on EditTierCredentialsURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *EditTierCredentialsURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *EditTierCredentialsURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *EditTierCredentialsURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on EditTierCredentialsURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on EditTierCredentialsURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *EditTierCredentialsURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/admin_api/get_tier.go b/restapi/operations/admin_api/get_tier.go new file mode 100644 index 0000000000..3a644754de --- /dev/null +++ b/restapi/operations/admin_api/get_tier.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// GetTierHandlerFunc turns a function with the right signature into a get tier handler +type GetTierHandlerFunc func(GetTierParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetTierHandlerFunc) Handle(params GetTierParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// GetTierHandler interface for that can handle valid get tier params +type GetTierHandler interface { + Handle(GetTierParams, *models.Principal) middleware.Responder +} + +// NewGetTier creates a new http.Handler for the get tier operation +func NewGetTier(ctx *middleware.Context, handler GetTierHandler) *GetTier { + return &GetTier{Context: ctx, Handler: handler} +} + +/*GetTier swagger:route GET /admin/tiers/{type}/{name} AdminAPI getTier + +Get Tier + +*/ +type GetTier struct { + Context *middleware.Context + Handler GetTierHandler +} + +func (o *GetTier) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewGetTierParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/admin_api/get_tier_parameters.go b/restapi/operations/admin_api/get_tier_parameters.go new file mode 100644 index 0000000000..0fd4f94311 --- /dev/null +++ b/restapi/operations/admin_api/get_tier_parameters.go @@ -0,0 +1,129 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/validate" +) + +// NewGetTierParams creates a new GetTierParams object +// no default values defined in spec. +func NewGetTierParams() GetTierParams { + + return GetTierParams{} +} + +// GetTierParams contains all the bound params for the get tier operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetTier +type GetTierParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + Name string + /* + Required: true + In: path + */ + Type string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetTierParams() beforehand. +func (o *GetTierParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rName, rhkName, _ := route.Params.GetOK("name") + if err := o.bindName(rName, rhkName, route.Formats); err != nil { + res = append(res, err) + } + + rType, rhkType, _ := route.Params.GetOK("type") + if err := o.bindType(rType, rhkType, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindName binds and validates parameter Name from path. +func (o *GetTierParams) bindName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.Name = raw + + return nil +} + +// bindType binds and validates parameter Type from path. +func (o *GetTierParams) bindType(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.Type = raw + + if err := o.validateType(formats); err != nil { + return err + } + + return nil +} + +// validateType carries on validations for parameter Type +func (o *GetTierParams) validateType(formats strfmt.Registry) error { + + if err := validate.EnumCase("type", "path", o.Type, []interface{}{"s3", "gcs", "azure"}, true); err != nil { + return err + } + + return nil +} diff --git a/restapi/operations/admin_api/get_tier_responses.go b/restapi/operations/admin_api/get_tier_responses.go new file mode 100644 index 0000000000..7cab2683d6 --- /dev/null +++ b/restapi/operations/admin_api/get_tier_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// GetTierOKCode is the HTTP code returned for type GetTierOK +const GetTierOKCode int = 200 + +/*GetTierOK A successful response. + +swagger:response getTierOK +*/ +type GetTierOK struct { + + /* + In: Body + */ + Payload *models.Tier `json:"body,omitempty"` +} + +// NewGetTierOK creates GetTierOK with default headers values +func NewGetTierOK() *GetTierOK { + + return &GetTierOK{} +} + +// WithPayload adds the payload to the get tier o k response +func (o *GetTierOK) WithPayload(payload *models.Tier) *GetTierOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get tier o k response +func (o *GetTierOK) SetPayload(payload *models.Tier) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetTierOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/*GetTierDefault Generic error response. + +swagger:response getTierDefault +*/ +type GetTierDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetTierDefault creates GetTierDefault with default headers values +func NewGetTierDefault(code int) *GetTierDefault { + if code <= 0 { + code = 500 + } + + return &GetTierDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the get tier default response +func (o *GetTierDefault) WithStatusCode(code int) *GetTierDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the get tier default response +func (o *GetTierDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the get tier default response +func (o *GetTierDefault) WithPayload(payload *models.Error) *GetTierDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get tier default response +func (o *GetTierDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetTierDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/admin_api/get_tier_urlbuilder.go b/restapi/operations/admin_api/get_tier_urlbuilder.go new file mode 100644 index 0000000000..4d23453743 --- /dev/null +++ b/restapi/operations/admin_api/get_tier_urlbuilder.go @@ -0,0 +1,124 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// GetTierURL generates an URL for the get tier operation +type GetTierURL struct { + Name string + Type string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetTierURL) WithBasePath(bp string) *GetTierURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetTierURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetTierURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/admin/tiers/{type}/{name}" + + name := o.Name + if name != "" { + _path = strings.Replace(_path, "{name}", name, -1) + } else { + return nil, errors.New("name is required on GetTierURL") + } + + typeVar := o.Type + if typeVar != "" { + _path = strings.Replace(_path, "{type}", typeVar, -1) + } else { + return nil, errors.New("type is required on GetTierURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetTierURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetTierURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetTierURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetTierURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetTierURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetTierURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/admin_api/tiers_list.go b/restapi/operations/admin_api/tiers_list.go new file mode 100644 index 0000000000..03af11ca0d --- /dev/null +++ b/restapi/operations/admin_api/tiers_list.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// TiersListHandlerFunc turns a function with the right signature into a tiers list handler +type TiersListHandlerFunc func(TiersListParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn TiersListHandlerFunc) Handle(params TiersListParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// TiersListHandler interface for that can handle valid tiers list params +type TiersListHandler interface { + Handle(TiersListParams, *models.Principal) middleware.Responder +} + +// NewTiersList creates a new http.Handler for the tiers list operation +func NewTiersList(ctx *middleware.Context, handler TiersListHandler) *TiersList { + return &TiersList{Context: ctx, Handler: handler} +} + +/*TiersList swagger:route GET /admin/tiers AdminAPI tiersList + +Returns a list of tiers for ilm + +*/ +type TiersList struct { + Context *middleware.Context + Handler TiersListHandler +} + +func (o *TiersList) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewTiersListParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/admin_api/tiers_list_parameters.go b/restapi/operations/admin_api/tiers_list_parameters.go new file mode 100644 index 0000000000..6373917b32 --- /dev/null +++ b/restapi/operations/admin_api/tiers_list_parameters.go @@ -0,0 +1,62 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" +) + +// NewTiersListParams creates a new TiersListParams object +// no default values defined in spec. +func NewTiersListParams() TiersListParams { + + return TiersListParams{} +} + +// TiersListParams contains all the bound params for the tiers list operation +// typically these are obtained from a http.Request +// +// swagger:parameters TiersList +type TiersListParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewTiersListParams() beforehand. +func (o *TiersListParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} diff --git a/restapi/operations/admin_api/tiers_list_responses.go b/restapi/operations/admin_api/tiers_list_responses.go new file mode 100644 index 0000000000..bdf2540239 --- /dev/null +++ b/restapi/operations/admin_api/tiers_list_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// TiersListOKCode is the HTTP code returned for type TiersListOK +const TiersListOKCode int = 200 + +/*TiersListOK A successful response. + +swagger:response tiersListOK +*/ +type TiersListOK struct { + + /* + In: Body + */ + Payload *models.TierListResponse `json:"body,omitempty"` +} + +// NewTiersListOK creates TiersListOK with default headers values +func NewTiersListOK() *TiersListOK { + + return &TiersListOK{} +} + +// WithPayload adds the payload to the tiers list o k response +func (o *TiersListOK) WithPayload(payload *models.TierListResponse) *TiersListOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the tiers list o k response +func (o *TiersListOK) SetPayload(payload *models.TierListResponse) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *TiersListOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/*TiersListDefault Generic error response. + +swagger:response tiersListDefault +*/ +type TiersListDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewTiersListDefault creates TiersListDefault with default headers values +func NewTiersListDefault(code int) *TiersListDefault { + if code <= 0 { + code = 500 + } + + return &TiersListDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the tiers list default response +func (o *TiersListDefault) WithStatusCode(code int) *TiersListDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the tiers list default response +func (o *TiersListDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the tiers list default response +func (o *TiersListDefault) WithPayload(payload *models.Error) *TiersListDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the tiers list default response +func (o *TiersListDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *TiersListDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/admin_api/tiers_list_urlbuilder.go b/restapi/operations/admin_api/tiers_list_urlbuilder.go new file mode 100644 index 0000000000..ef86aa0238 --- /dev/null +++ b/restapi/operations/admin_api/tiers_list_urlbuilder.go @@ -0,0 +1,104 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package admin_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" +) + +// TiersListURL generates an URL for the tiers list operation +type TiersListURL struct { + _basePath string +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TiersListURL) WithBasePath(bp string) *TiersListURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TiersListURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *TiersListURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/admin/tiers" + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *TiersListURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *TiersListURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *TiersListURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on TiersListURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on TiersListURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *TiersListURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/console_api.go b/restapi/operations/console_api.go index 02235d71d7..0bed3e6154 100644 --- a/restapi/operations/console_api.go +++ b/restapi/operations/console_api.go @@ -67,6 +67,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { UserAPIAccountChangePasswordHandler: user_api.AccountChangePasswordHandlerFunc(func(params user_api.AccountChangePasswordParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.AccountChangePassword has not yet been implemented") }), + UserAPIAddBucketLifecycleHandler: user_api.AddBucketLifecycleHandlerFunc(func(params user_api.AddBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation user_api.AddBucketLifecycle has not yet been implemented") + }), UserAPIAddBucketReplicationHandler: user_api.AddBucketReplicationHandlerFunc(func(params user_api.AddBucketReplicationParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.AddBucketReplication has not yet been implemented") }), @@ -82,6 +85,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { UserAPIAddRemoteBucketHandler: user_api.AddRemoteBucketHandlerFunc(func(params user_api.AddRemoteBucketParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.AddRemoteBucket has not yet been implemented") }), + AdminAPIAddTierHandler: admin_api.AddTierHandlerFunc(func(params admin_api.AddTierParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin_api.AddTier has not yet been implemented") + }), AdminAPIAddUserHandler: admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation admin_api.AddUser has not yet been implemented") }), @@ -139,12 +145,18 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { UserAPIDownloadObjectHandler: user_api.DownloadObjectHandlerFunc(func(params user_api.DownloadObjectParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.DownloadObject has not yet been implemented") }), + AdminAPIEditTierCredentialsHandler: admin_api.EditTierCredentialsHandlerFunc(func(params admin_api.EditTierCredentialsParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin_api.EditTierCredentials has not yet been implemented") + }), UserAPIEnableBucketEncryptionHandler: user_api.EnableBucketEncryptionHandlerFunc(func(params user_api.EnableBucketEncryptionParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.EnableBucketEncryption has not yet been implemented") }), UserAPIGetBucketEncryptionInfoHandler: user_api.GetBucketEncryptionInfoHandlerFunc(func(params user_api.GetBucketEncryptionInfoParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.GetBucketEncryptionInfo has not yet been implemented") }), + UserAPIGetBucketLifecycleHandler: user_api.GetBucketLifecycleHandlerFunc(func(params user_api.GetBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation user_api.GetBucketLifecycle has not yet been implemented") + }), UserAPIGetBucketQuotaHandler: user_api.GetBucketQuotaHandlerFunc(func(params user_api.GetBucketQuotaParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation user_api.GetBucketQuota has not yet been implemented") }), @@ -169,6 +181,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { AdminAPIGetTenantUsageHandler: admin_api.GetTenantUsageHandlerFunc(func(params admin_api.GetTenantUsageParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation admin_api.GetTenantUsage has not yet been implemented") }), + AdminAPIGetTierHandler: admin_api.GetTierHandlerFunc(func(params admin_api.GetTierParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin_api.GetTier has not yet been implemented") + }), AdminAPIGetUserInfoHandler: admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation admin_api.GetUserInfo has not yet been implemented") }), @@ -316,6 +331,12 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI { AdminAPITenantUpdatePoolsHandler: admin_api.TenantUpdatePoolsHandlerFunc(func(params admin_api.TenantUpdatePoolsParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation admin_api.TenantUpdatePools has not yet been implemented") }), + AdminAPITiersListHandler: admin_api.TiersListHandlerFunc(func(params admin_api.TiersListParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation admin_api.TiersList has not yet been implemented") + }), + UserAPIUpdateBucketLifecycleHandler: user_api.UpdateBucketLifecycleHandlerFunc(func(params user_api.UpdateBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation user_api.UpdateBucketLifecycle has not yet been implemented") + }), AdminAPIUpdateGroupHandler: admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation admin_api.UpdateGroup has not yet been implemented") }), @@ -382,6 +403,8 @@ type ConsoleAPI struct { // UserAPIAccountChangePasswordHandler sets the operation handler for the account change password operation UserAPIAccountChangePasswordHandler user_api.AccountChangePasswordHandler + // UserAPIAddBucketLifecycleHandler sets the operation handler for the add bucket lifecycle operation + UserAPIAddBucketLifecycleHandler user_api.AddBucketLifecycleHandler // UserAPIAddBucketReplicationHandler sets the operation handler for the add bucket replication operation UserAPIAddBucketReplicationHandler user_api.AddBucketReplicationHandler // AdminAPIAddGroupHandler sets the operation handler for the add group operation @@ -392,6 +415,8 @@ type ConsoleAPI struct { AdminAPIAddPolicyHandler admin_api.AddPolicyHandler // UserAPIAddRemoteBucketHandler sets the operation handler for the add remote bucket operation UserAPIAddRemoteBucketHandler user_api.AddRemoteBucketHandler + // AdminAPIAddTierHandler sets the operation handler for the add tier operation + AdminAPIAddTierHandler admin_api.AddTierHandler // AdminAPIAddUserHandler sets the operation handler for the add user operation AdminAPIAddUserHandler admin_api.AddUserHandler // AdminAPIAdminInfoHandler sets the operation handler for the admin info operation @@ -430,10 +455,14 @@ type ConsoleAPI struct { UserAPIDisableBucketEncryptionHandler user_api.DisableBucketEncryptionHandler // UserAPIDownloadObjectHandler sets the operation handler for the download object operation UserAPIDownloadObjectHandler user_api.DownloadObjectHandler + // AdminAPIEditTierCredentialsHandler sets the operation handler for the edit tier credentials operation + AdminAPIEditTierCredentialsHandler admin_api.EditTierCredentialsHandler // UserAPIEnableBucketEncryptionHandler sets the operation handler for the enable bucket encryption operation UserAPIEnableBucketEncryptionHandler user_api.EnableBucketEncryptionHandler // UserAPIGetBucketEncryptionInfoHandler sets the operation handler for the get bucket encryption info operation UserAPIGetBucketEncryptionInfoHandler user_api.GetBucketEncryptionInfoHandler + // UserAPIGetBucketLifecycleHandler sets the operation handler for the get bucket lifecycle operation + UserAPIGetBucketLifecycleHandler user_api.GetBucketLifecycleHandler // UserAPIGetBucketQuotaHandler sets the operation handler for the get bucket quota operation UserAPIGetBucketQuotaHandler user_api.GetBucketQuotaHandler // UserAPIGetBucketReplicationHandler sets the operation handler for the get bucket replication operation @@ -450,6 +479,8 @@ type ConsoleAPI struct { AdminAPIGetResourceQuotaHandler admin_api.GetResourceQuotaHandler // AdminAPIGetTenantUsageHandler sets the operation handler for the get tenant usage operation AdminAPIGetTenantUsageHandler admin_api.GetTenantUsageHandler + // AdminAPIGetTierHandler sets the operation handler for the get tier operation + AdminAPIGetTierHandler admin_api.GetTierHandler // AdminAPIGetUserInfoHandler sets the operation handler for the get user info operation AdminAPIGetUserInfoHandler admin_api.GetUserInfoHandler // AdminAPIGroupInfoHandler sets the operation handler for the group info operation @@ -548,6 +579,10 @@ type ConsoleAPI struct { AdminAPITenantUpdateEncryptionHandler admin_api.TenantUpdateEncryptionHandler // AdminAPITenantUpdatePoolsHandler sets the operation handler for the tenant update pools operation AdminAPITenantUpdatePoolsHandler admin_api.TenantUpdatePoolsHandler + // AdminAPITiersListHandler sets the operation handler for the tiers list operation + AdminAPITiersListHandler admin_api.TiersListHandler + // UserAPIUpdateBucketLifecycleHandler sets the operation handler for the update bucket lifecycle operation + UserAPIUpdateBucketLifecycleHandler user_api.UpdateBucketLifecycleHandler // AdminAPIUpdateGroupHandler sets the operation handler for the update group operation AdminAPIUpdateGroupHandler admin_api.UpdateGroupHandler // AdminAPIUpdateTenantHandler sets the operation handler for the update tenant operation @@ -635,6 +670,9 @@ func (o *ConsoleAPI) Validate() error { if o.UserAPIAccountChangePasswordHandler == nil { unregistered = append(unregistered, "user_api.AccountChangePasswordHandler") } + if o.UserAPIAddBucketLifecycleHandler == nil { + unregistered = append(unregistered, "user_api.AddBucketLifecycleHandler") + } if o.UserAPIAddBucketReplicationHandler == nil { unregistered = append(unregistered, "user_api.AddBucketReplicationHandler") } @@ -650,6 +688,9 @@ func (o *ConsoleAPI) Validate() error { if o.UserAPIAddRemoteBucketHandler == nil { unregistered = append(unregistered, "user_api.AddRemoteBucketHandler") } + if o.AdminAPIAddTierHandler == nil { + unregistered = append(unregistered, "admin_api.AddTierHandler") + } if o.AdminAPIAddUserHandler == nil { unregistered = append(unregistered, "admin_api.AddUserHandler") } @@ -707,12 +748,18 @@ func (o *ConsoleAPI) Validate() error { if o.UserAPIDownloadObjectHandler == nil { unregistered = append(unregistered, "user_api.DownloadObjectHandler") } + if o.AdminAPIEditTierCredentialsHandler == nil { + unregistered = append(unregistered, "admin_api.EditTierCredentialsHandler") + } if o.UserAPIEnableBucketEncryptionHandler == nil { unregistered = append(unregistered, "user_api.EnableBucketEncryptionHandler") } if o.UserAPIGetBucketEncryptionInfoHandler == nil { unregistered = append(unregistered, "user_api.GetBucketEncryptionInfoHandler") } + if o.UserAPIGetBucketLifecycleHandler == nil { + unregistered = append(unregistered, "user_api.GetBucketLifecycleHandler") + } if o.UserAPIGetBucketQuotaHandler == nil { unregistered = append(unregistered, "user_api.GetBucketQuotaHandler") } @@ -737,6 +784,9 @@ func (o *ConsoleAPI) Validate() error { if o.AdminAPIGetTenantUsageHandler == nil { unregistered = append(unregistered, "admin_api.GetTenantUsageHandler") } + if o.AdminAPIGetTierHandler == nil { + unregistered = append(unregistered, "admin_api.GetTierHandler") + } if o.AdminAPIGetUserInfoHandler == nil { unregistered = append(unregistered, "admin_api.GetUserInfoHandler") } @@ -884,6 +934,12 @@ func (o *ConsoleAPI) Validate() error { if o.AdminAPITenantUpdatePoolsHandler == nil { unregistered = append(unregistered, "admin_api.TenantUpdatePoolsHandler") } + if o.AdminAPITiersListHandler == nil { + unregistered = append(unregistered, "admin_api.TiersListHandler") + } + if o.UserAPIUpdateBucketLifecycleHandler == nil { + unregistered = append(unregistered, "user_api.UpdateBucketLifecycleHandler") + } if o.AdminAPIUpdateGroupHandler == nil { unregistered = append(unregistered, "admin_api.UpdateGroupHandler") } @@ -1005,6 +1061,10 @@ func (o *ConsoleAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } + o.handlers["POST"]["/buckets/{bucket_name}/lifecycle"] = user_api.NewAddBucketLifecycle(o.context, o.UserAPIAddBucketLifecycleHandler) + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } o.handlers["POST"]["/buckets/{bucket_name}/replication"] = user_api.NewAddBucketReplication(o.context, o.UserAPIAddBucketReplicationHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) @@ -1025,6 +1085,10 @@ func (o *ConsoleAPI) initHandlerCache() { if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } + o.handlers["POST"]["/admin/tiers"] = admin_api.NewAddTier(o.context, o.AdminAPIAddTierHandler) + if o.handlers["POST"] == nil { + o.handlers["POST"] = make(map[string]http.Handler) + } o.handlers["POST"]["/users"] = admin_api.NewAddUser(o.context, o.AdminAPIAddUserHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) @@ -1098,6 +1162,10 @@ func (o *ConsoleAPI) initHandlerCache() { o.handlers["GET"] = make(map[string]http.Handler) } o.handlers["GET"]["/buckets/{bucket_name}/objects/download"] = user_api.NewDownloadObject(o.context, o.UserAPIDownloadObjectHandler) + if o.handlers["PUT"] == nil { + o.handlers["PUT"] = make(map[string]http.Handler) + } + o.handlers["PUT"]["/admin/tiers/{type}/{name}/credentials"] = admin_api.NewEditTierCredentials(o.context, o.AdminAPIEditTierCredentialsHandler) if o.handlers["POST"] == nil { o.handlers["POST"] = make(map[string]http.Handler) } @@ -1109,6 +1177,10 @@ func (o *ConsoleAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/buckets/{bucket_name}/lifecycle"] = user_api.NewGetBucketLifecycle(o.context, o.UserAPIGetBucketLifecycleHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/buckets/{name}/quota"] = user_api.NewGetBucketQuota(o.context, o.UserAPIGetBucketQuotaHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) @@ -1141,6 +1213,10 @@ func (o *ConsoleAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/admin/tiers/{type}/{name}"] = admin_api.NewGetTier(o.context, o.AdminAPIGetTierHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/users/{name}"] = admin_api.NewGetUserInfo(o.context, o.AdminAPIGetUserInfoHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) @@ -1334,6 +1410,14 @@ func (o *ConsoleAPI) initHandlerCache() { o.handlers["PUT"] = make(map[string]http.Handler) } o.handlers["PUT"]["/namespaces/{namespace}/tenants/{tenant}/pools"] = admin_api.NewTenantUpdatePools(o.context, o.AdminAPITenantUpdatePoolsHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } + o.handlers["GET"]["/admin/tiers"] = admin_api.NewTiersList(o.context, o.AdminAPITiersListHandler) + if o.handlers["PUT"] == nil { + o.handlers["PUT"] = make(map[string]http.Handler) + } + o.handlers["PUT"]["/buckets/{bucket_name}/lifecycle/{lifecycle_id}"] = user_api.NewUpdateBucketLifecycle(o.context, o.UserAPIUpdateBucketLifecycleHandler) if o.handlers["PUT"] == nil { o.handlers["PUT"] = make(map[string]http.Handler) } diff --git a/restapi/operations/user_api/add_bucket_lifecycle.go b/restapi/operations/user_api/add_bucket_lifecycle.go new file mode 100644 index 0000000000..8f18677f18 --- /dev/null +++ b/restapi/operations/user_api/add_bucket_lifecycle.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// AddBucketLifecycleHandlerFunc turns a function with the right signature into a add bucket lifecycle handler +type AddBucketLifecycleHandlerFunc func(AddBucketLifecycleParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn AddBucketLifecycleHandlerFunc) Handle(params AddBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// AddBucketLifecycleHandler interface for that can handle valid add bucket lifecycle params +type AddBucketLifecycleHandler interface { + Handle(AddBucketLifecycleParams, *models.Principal) middleware.Responder +} + +// NewAddBucketLifecycle creates a new http.Handler for the add bucket lifecycle operation +func NewAddBucketLifecycle(ctx *middleware.Context, handler AddBucketLifecycleHandler) *AddBucketLifecycle { + return &AddBucketLifecycle{Context: ctx, Handler: handler} +} + +/*AddBucketLifecycle swagger:route POST /buckets/{bucket_name}/lifecycle UserAPI addBucketLifecycle + +Add Bucket Lifecycle + +*/ +type AddBucketLifecycle struct { + Context *middleware.Context + Handler AddBucketLifecycleHandler +} + +func (o *AddBucketLifecycle) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewAddBucketLifecycleParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/user_api/add_bucket_lifecycle_parameters.go b/restapi/operations/user_api/add_bucket_lifecycle_parameters.go new file mode 100644 index 0000000000..1b6c90281a --- /dev/null +++ b/restapi/operations/user_api/add_bucket_lifecycle_parameters.go @@ -0,0 +1,120 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + + "github.com/minio/console/models" +) + +// NewAddBucketLifecycleParams creates a new AddBucketLifecycleParams object +// no default values defined in spec. +func NewAddBucketLifecycleParams() AddBucketLifecycleParams { + + return AddBucketLifecycleParams{} +} + +// AddBucketLifecycleParams contains all the bound params for the add bucket lifecycle operation +// typically these are obtained from a http.Request +// +// swagger:parameters AddBucketLifecycle +type AddBucketLifecycleParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: body + */ + Body *models.AddBucketLifecycle + /* + Required: true + In: path + */ + BucketName string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewAddBucketLifecycleParams() beforehand. +func (o *AddBucketLifecycleParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.AddBucketLifecycle + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("body", "body", "")) + } else { + res = append(res, errors.NewParseError("body", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Body = &body + } + } + } else { + res = append(res, errors.Required("body", "body", "")) + } + rBucketName, rhkBucketName, _ := route.Params.GetOK("bucket_name") + if err := o.bindBucketName(rBucketName, rhkBucketName, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindBucketName binds and validates parameter BucketName from path. +func (o *AddBucketLifecycleParams) bindBucketName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.BucketName = raw + + return nil +} diff --git a/restapi/operations/user_api/add_bucket_lifecycle_responses.go b/restapi/operations/user_api/add_bucket_lifecycle_responses.go new file mode 100644 index 0000000000..87ad58c274 --- /dev/null +++ b/restapi/operations/user_api/add_bucket_lifecycle_responses.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// AddBucketLifecycleCreatedCode is the HTTP code returned for type AddBucketLifecycleCreated +const AddBucketLifecycleCreatedCode int = 201 + +/*AddBucketLifecycleCreated A successful response. + +swagger:response addBucketLifecycleCreated +*/ +type AddBucketLifecycleCreated struct { +} + +// NewAddBucketLifecycleCreated creates AddBucketLifecycleCreated with default headers values +func NewAddBucketLifecycleCreated() *AddBucketLifecycleCreated { + + return &AddBucketLifecycleCreated{} +} + +// WriteResponse to the client +func (o *AddBucketLifecycleCreated) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(201) +} + +/*AddBucketLifecycleDefault Generic error response. + +swagger:response addBucketLifecycleDefault +*/ +type AddBucketLifecycleDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewAddBucketLifecycleDefault creates AddBucketLifecycleDefault with default headers values +func NewAddBucketLifecycleDefault(code int) *AddBucketLifecycleDefault { + if code <= 0 { + code = 500 + } + + return &AddBucketLifecycleDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the add bucket lifecycle default response +func (o *AddBucketLifecycleDefault) WithStatusCode(code int) *AddBucketLifecycleDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the add bucket lifecycle default response +func (o *AddBucketLifecycleDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the add bucket lifecycle default response +func (o *AddBucketLifecycleDefault) WithPayload(payload *models.Error) *AddBucketLifecycleDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the add bucket lifecycle default response +func (o *AddBucketLifecycleDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *AddBucketLifecycleDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/user_api/add_bucket_lifecycle_urlbuilder.go b/restapi/operations/user_api/add_bucket_lifecycle_urlbuilder.go new file mode 100644 index 0000000000..1f9d8ccdce --- /dev/null +++ b/restapi/operations/user_api/add_bucket_lifecycle_urlbuilder.go @@ -0,0 +1,116 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// AddBucketLifecycleURL generates an URL for the add bucket lifecycle operation +type AddBucketLifecycleURL struct { + BucketName string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AddBucketLifecycleURL) WithBasePath(bp string) *AddBucketLifecycleURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *AddBucketLifecycleURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *AddBucketLifecycleURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/buckets/{bucket_name}/lifecycle" + + bucketName := o.BucketName + if bucketName != "" { + _path = strings.Replace(_path, "{bucket_name}", bucketName, -1) + } else { + return nil, errors.New("bucketName is required on AddBucketLifecycleURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *AddBucketLifecycleURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *AddBucketLifecycleURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *AddBucketLifecycleURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on AddBucketLifecycleURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on AddBucketLifecycleURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *AddBucketLifecycleURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/user_api/get_bucket_lifecycle.go b/restapi/operations/user_api/get_bucket_lifecycle.go new file mode 100644 index 0000000000..2cc6b86a03 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_lifecycle.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// GetBucketLifecycleHandlerFunc turns a function with the right signature into a get bucket lifecycle handler +type GetBucketLifecycleHandlerFunc func(GetBucketLifecycleParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn GetBucketLifecycleHandlerFunc) Handle(params GetBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// GetBucketLifecycleHandler interface for that can handle valid get bucket lifecycle params +type GetBucketLifecycleHandler interface { + Handle(GetBucketLifecycleParams, *models.Principal) middleware.Responder +} + +// NewGetBucketLifecycle creates a new http.Handler for the get bucket lifecycle operation +func NewGetBucketLifecycle(ctx *middleware.Context, handler GetBucketLifecycleHandler) *GetBucketLifecycle { + return &GetBucketLifecycle{Context: ctx, Handler: handler} +} + +/*GetBucketLifecycle swagger:route GET /buckets/{bucket_name}/lifecycle UserAPI getBucketLifecycle + +Bucket Lifecycle + +*/ +type GetBucketLifecycle struct { + Context *middleware.Context + Handler GetBucketLifecycleHandler +} + +func (o *GetBucketLifecycle) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewGetBucketLifecycleParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/user_api/get_bucket_lifecycle_parameters.go b/restapi/operations/user_api/get_bucket_lifecycle_parameters.go new file mode 100644 index 0000000000..c5dd9c6e78 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_lifecycle_parameters.go @@ -0,0 +1,89 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" +) + +// NewGetBucketLifecycleParams creates a new GetBucketLifecycleParams object +// no default values defined in spec. +func NewGetBucketLifecycleParams() GetBucketLifecycleParams { + + return GetBucketLifecycleParams{} +} + +// GetBucketLifecycleParams contains all the bound params for the get bucket lifecycle operation +// typically these are obtained from a http.Request +// +// swagger:parameters GetBucketLifecycle +type GetBucketLifecycleParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + BucketName string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewGetBucketLifecycleParams() beforehand. +func (o *GetBucketLifecycleParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rBucketName, rhkBucketName, _ := route.Params.GetOK("bucket_name") + if err := o.bindBucketName(rBucketName, rhkBucketName, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindBucketName binds and validates parameter BucketName from path. +func (o *GetBucketLifecycleParams) bindBucketName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.BucketName = raw + + return nil +} diff --git a/restapi/operations/user_api/get_bucket_lifecycle_responses.go b/restapi/operations/user_api/get_bucket_lifecycle_responses.go new file mode 100644 index 0000000000..ad3c557a78 --- /dev/null +++ b/restapi/operations/user_api/get_bucket_lifecycle_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// GetBucketLifecycleOKCode is the HTTP code returned for type GetBucketLifecycleOK +const GetBucketLifecycleOKCode int = 200 + +/*GetBucketLifecycleOK A successful response. + +swagger:response getBucketLifecycleOK +*/ +type GetBucketLifecycleOK struct { + + /* + In: Body + */ + Payload *models.BucketLifecycleResponse `json:"body,omitempty"` +} + +// NewGetBucketLifecycleOK creates GetBucketLifecycleOK with default headers values +func NewGetBucketLifecycleOK() *GetBucketLifecycleOK { + + return &GetBucketLifecycleOK{} +} + +// WithPayload adds the payload to the get bucket lifecycle o k response +func (o *GetBucketLifecycleOK) WithPayload(payload *models.BucketLifecycleResponse) *GetBucketLifecycleOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get bucket lifecycle o k response +func (o *GetBucketLifecycleOK) SetPayload(payload *models.BucketLifecycleResponse) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetBucketLifecycleOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/*GetBucketLifecycleDefault Generic error response. + +swagger:response getBucketLifecycleDefault +*/ +type GetBucketLifecycleDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewGetBucketLifecycleDefault creates GetBucketLifecycleDefault with default headers values +func NewGetBucketLifecycleDefault(code int) *GetBucketLifecycleDefault { + if code <= 0 { + code = 500 + } + + return &GetBucketLifecycleDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the get bucket lifecycle default response +func (o *GetBucketLifecycleDefault) WithStatusCode(code int) *GetBucketLifecycleDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the get bucket lifecycle default response +func (o *GetBucketLifecycleDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the get bucket lifecycle default response +func (o *GetBucketLifecycleDefault) WithPayload(payload *models.Error) *GetBucketLifecycleDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the get bucket lifecycle default response +func (o *GetBucketLifecycleDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *GetBucketLifecycleDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/user_api/get_bucket_lifecycle_urlbuilder.go b/restapi/operations/user_api/get_bucket_lifecycle_urlbuilder.go new file mode 100644 index 0000000000..6f844ea36f --- /dev/null +++ b/restapi/operations/user_api/get_bucket_lifecycle_urlbuilder.go @@ -0,0 +1,116 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// GetBucketLifecycleURL generates an URL for the get bucket lifecycle operation +type GetBucketLifecycleURL struct { + BucketName string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetBucketLifecycleURL) WithBasePath(bp string) *GetBucketLifecycleURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *GetBucketLifecycleURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *GetBucketLifecycleURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/buckets/{bucket_name}/lifecycle" + + bucketName := o.BucketName + if bucketName != "" { + _path = strings.Replace(_path, "{bucket_name}", bucketName, -1) + } else { + return nil, errors.New("bucketName is required on GetBucketLifecycleURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *GetBucketLifecycleURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *GetBucketLifecycleURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *GetBucketLifecycleURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on GetBucketLifecycleURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on GetBucketLifecycleURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *GetBucketLifecycleURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/operations/user_api/update_bucket_lifecycle.go b/restapi/operations/user_api/update_bucket_lifecycle.go new file mode 100644 index 0000000000..eec6c3d924 --- /dev/null +++ b/restapi/operations/user_api/update_bucket_lifecycle.go @@ -0,0 +1,90 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// UpdateBucketLifecycleHandlerFunc turns a function with the right signature into a update bucket lifecycle handler +type UpdateBucketLifecycleHandlerFunc func(UpdateBucketLifecycleParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn UpdateBucketLifecycleHandlerFunc) Handle(params UpdateBucketLifecycleParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// UpdateBucketLifecycleHandler interface for that can handle valid update bucket lifecycle params +type UpdateBucketLifecycleHandler interface { + Handle(UpdateBucketLifecycleParams, *models.Principal) middleware.Responder +} + +// NewUpdateBucketLifecycle creates a new http.Handler for the update bucket lifecycle operation +func NewUpdateBucketLifecycle(ctx *middleware.Context, handler UpdateBucketLifecycleHandler) *UpdateBucketLifecycle { + return &UpdateBucketLifecycle{Context: ctx, Handler: handler} +} + +/*UpdateBucketLifecycle swagger:route PUT /buckets/{bucket_name}/lifecycle/{lifecycle_id} UserAPI updateBucketLifecycle + +Update Lifecycle rule + +*/ +type UpdateBucketLifecycle struct { + Context *middleware.Context + Handler UpdateBucketLifecycleHandler +} + +func (o *UpdateBucketLifecycle) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + r = rCtx + } + var Params = NewUpdateBucketLifecycleParams() + + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + r = aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/restapi/operations/user_api/update_bucket_lifecycle_parameters.go b/restapi/operations/user_api/update_bucket_lifecycle_parameters.go new file mode 100644 index 0000000000..81a2220e81 --- /dev/null +++ b/restapi/operations/user_api/update_bucket_lifecycle_parameters.go @@ -0,0 +1,145 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "io" + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + + "github.com/minio/console/models" +) + +// NewUpdateBucketLifecycleParams creates a new UpdateBucketLifecycleParams object +// no default values defined in spec. +func NewUpdateBucketLifecycleParams() UpdateBucketLifecycleParams { + + return UpdateBucketLifecycleParams{} +} + +// UpdateBucketLifecycleParams contains all the bound params for the update bucket lifecycle operation +// typically these are obtained from a http.Request +// +// swagger:parameters UpdateBucketLifecycle +type UpdateBucketLifecycleParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: body + */ + Body *models.UpdateBucketLifecycle + /* + Required: true + In: path + */ + BucketName string + /* + Required: true + In: path + */ + LifecycleID string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewUpdateBucketLifecycleParams() beforehand. +func (o *UpdateBucketLifecycleParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + if runtime.HasBody(r) { + defer r.Body.Close() + var body models.UpdateBucketLifecycle + if err := route.Consumer.Consume(r.Body, &body); err != nil { + if err == io.EOF { + res = append(res, errors.Required("body", "body", "")) + } else { + res = append(res, errors.NewParseError("body", "body", "", err)) + } + } else { + // validate body object + if err := body.Validate(route.Formats); err != nil { + res = append(res, err) + } + + if len(res) == 0 { + o.Body = &body + } + } + } else { + res = append(res, errors.Required("body", "body", "")) + } + rBucketName, rhkBucketName, _ := route.Params.GetOK("bucket_name") + if err := o.bindBucketName(rBucketName, rhkBucketName, route.Formats); err != nil { + res = append(res, err) + } + + rLifecycleID, rhkLifecycleID, _ := route.Params.GetOK("lifecycle_id") + if err := o.bindLifecycleID(rLifecycleID, rhkLifecycleID, route.Formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindBucketName binds and validates parameter BucketName from path. +func (o *UpdateBucketLifecycleParams) bindBucketName(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.BucketName = raw + + return nil +} + +// bindLifecycleID binds and validates parameter LifecycleID from path. +func (o *UpdateBucketLifecycleParams) bindLifecycleID(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + + o.LifecycleID = raw + + return nil +} diff --git a/restapi/operations/user_api/update_bucket_lifecycle_responses.go b/restapi/operations/user_api/update_bucket_lifecycle_responses.go new file mode 100644 index 0000000000..733f3b9704 --- /dev/null +++ b/restapi/operations/user_api/update_bucket_lifecycle_responses.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// UpdateBucketLifecycleOKCode is the HTTP code returned for type UpdateBucketLifecycleOK +const UpdateBucketLifecycleOKCode int = 200 + +/*UpdateBucketLifecycleOK A successful response. + +swagger:response updateBucketLifecycleOK +*/ +type UpdateBucketLifecycleOK struct { +} + +// NewUpdateBucketLifecycleOK creates UpdateBucketLifecycleOK with default headers values +func NewUpdateBucketLifecycleOK() *UpdateBucketLifecycleOK { + + return &UpdateBucketLifecycleOK{} +} + +// WriteResponse to the client +func (o *UpdateBucketLifecycleOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(200) +} + +/*UpdateBucketLifecycleDefault Generic error response. + +swagger:response updateBucketLifecycleDefault +*/ +type UpdateBucketLifecycleDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewUpdateBucketLifecycleDefault creates UpdateBucketLifecycleDefault with default headers values +func NewUpdateBucketLifecycleDefault(code int) *UpdateBucketLifecycleDefault { + if code <= 0 { + code = 500 + } + + return &UpdateBucketLifecycleDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the update bucket lifecycle default response +func (o *UpdateBucketLifecycleDefault) WithStatusCode(code int) *UpdateBucketLifecycleDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the update bucket lifecycle default response +func (o *UpdateBucketLifecycleDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the update bucket lifecycle default response +func (o *UpdateBucketLifecycleDefault) WithPayload(payload *models.Error) *UpdateBucketLifecycleDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the update bucket lifecycle default response +func (o *UpdateBucketLifecycleDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *UpdateBucketLifecycleDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/restapi/operations/user_api/update_bucket_lifecycle_urlbuilder.go b/restapi/operations/user_api/update_bucket_lifecycle_urlbuilder.go new file mode 100644 index 0000000000..5f78e5fa0b --- /dev/null +++ b/restapi/operations/user_api/update_bucket_lifecycle_urlbuilder.go @@ -0,0 +1,124 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// 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 . +// + +package user_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// UpdateBucketLifecycleURL generates an URL for the update bucket lifecycle operation +type UpdateBucketLifecycleURL struct { + BucketName string + LifecycleID string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *UpdateBucketLifecycleURL) WithBasePath(bp string) *UpdateBucketLifecycleURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *UpdateBucketLifecycleURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *UpdateBucketLifecycleURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/buckets/{bucket_name}/lifecycle/{lifecycle_id}" + + bucketName := o.BucketName + if bucketName != "" { + _path = strings.Replace(_path, "{bucket_name}", bucketName, -1) + } else { + return nil, errors.New("bucketName is required on UpdateBucketLifecycleURL") + } + + lifecycleID := o.LifecycleID + if lifecycleID != "" { + _path = strings.Replace(_path, "{lifecycle_id}", lifecycleID, -1) + } else { + return nil, errors.New("lifecycleId is required on UpdateBucketLifecycleURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *UpdateBucketLifecycleURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *UpdateBucketLifecycleURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *UpdateBucketLifecycleURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on UpdateBucketLifecycleURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on UpdateBucketLifecycleURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *UpdateBucketLifecycleURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/restapi/user_buckets_lifecycle.go b/restapi/user_buckets_lifecycle.go new file mode 100644 index 0000000000..1ea1a87fc3 --- /dev/null +++ b/restapi/user_buckets_lifecycle.go @@ -0,0 +1,248 @@ +// 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 . + +package restapi + +import ( + "context" + "errors" + "strconv" + "strings" + "time" + + "github.com/rs/xid" + + "github.com/minio/mc/pkg/probe" + + "github.com/minio/mc/cmd/ilm" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/lifecycle" + + "github.com/go-openapi/runtime/middleware" + "github.com/minio/console/models" + "github.com/minio/console/restapi/operations" + "github.com/minio/console/restapi/operations/user_api" +) + +func registerBucketsLifecycleHandlers(api *operations.ConsoleAPI) { + api.UserAPIGetBucketLifecycleHandler = user_api.GetBucketLifecycleHandlerFunc(func(params user_api.GetBucketLifecycleParams, session *models.Principal) middleware.Responder { + listBucketLifecycleResponse, err := getBucketLifecycleResponse(session, params) + if err != nil { + return user_api.NewGetBucketLifecycleDefault(int(err.Code)).WithPayload(err) + } + return user_api.NewGetBucketLifecycleOK().WithPayload(listBucketLifecycleResponse) + }) + api.UserAPIAddBucketLifecycleHandler = user_api.AddBucketLifecycleHandlerFunc(func(params user_api.AddBucketLifecycleParams, session *models.Principal) middleware.Responder { + err := getAddBucketLifecycleResponse(session, params) + if err != nil { + return user_api.NewAddBucketLifecycleDefault(int(err.Code)).WithPayload(err) + } + return user_api.NewAddBucketLifecycleCreated() + }) +} + +// getBucketLifecycle() gets lifecycle lists for a bucket from MinIO API and returns their implementations +func getBucketLifecycle(ctx context.Context, client MinioClient, bucketName string) (*models.BucketLifecycleResponse, error) { + lifecycleList, err := client.getLifecycleRules(ctx, bucketName) + if err != nil { + return nil, err + } + + var rules []*models.ObjectBucketLifecycle + + for _, rule := range lifecycleList.Rules { + + var tags []*models.LifecycleTag + + for _, tagData := range rule.RuleFilter.And.Tags { + tags = append(tags, &models.LifecycleTag{ + Key: tagData.Key, + Value: tagData.Value, + }) + } + + rules = append(rules, &models.ObjectBucketLifecycle{ + ID: rule.ID, + Status: rule.Status, + Prefix: rule.RuleFilter.And.Prefix, + Expiration: &models.ExpirationResponse{Date: rule.Expiration.Date.Format(time.RFC3339), Days: int64(rule.Expiration.Days), DeleteMarker: rule.Expiration.DeleteMarker.IsEnabled()}, + Transition: &models.TransitionResponse{Date: rule.Transition.Date.Format(time.RFC3339), Days: int64(rule.Transition.Days), StorageClass: rule.Transition.StorageClass}, + Tags: tags, + }) + } + + // serialize output + lifecycleBucketsResponse := &models.BucketLifecycleResponse{ + Lifecycle: rules, + } + + return lifecycleBucketsResponse, nil +} + +// getBucketLifecycleResponse performs getBucketLifecycle() and serializes it to the handler's output +func getBucketLifecycleResponse(session *models.Principal, params user_api.GetBucketLifecycleParams) (*models.BucketLifecycleResponse, *models.Error) { + ctx := context.Background() + mClient, err := newMinioClient(session) + if err != nil { + return nil, prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + minioClient := minioClient{client: mClient} + + bucketEvents, err := getBucketLifecycle(ctx, minioClient, params.BucketName) + if err != nil { + return nil, prepareError(err) + } + return bucketEvents, nil +} + +// addBucketLifecycle gets lifecycle lists for a bucket from MinIO API and returns their implementations +func addBucketLifecycle(ctx context.Context, client MinioClient, params user_api.AddBucketLifecycleParams) error { + // Configuration that is already set. + lfcCfg, err := client.getLifecycleRules(ctx, params.BucketName) + if err != nil { + if e := err; minio.ToErrorResponse(e).Code == "NoSuchLifecycleConfiguration" { + lfcCfg = lifecycle.NewConfiguration() + } else { + return err + } + } + + id := xid.New().String() + + opts := ilm.LifecycleOptions{} + + // Verify if transition items are set + if params.Body.ExpiryDate == "" && params.Body.ExpiryDays == 0 { + if params.Body.TransitionDate != "" && params.Body.TransitionDays != 0 { + return errors.New("only one transition configuration can be set (days or date)") + } + + if params.Body.ExpiryDate != "" || params.Body.ExpiryDays != 0 { + return errors.New("expiry cannot be set when transition is being configured") + } + + if params.Body.NoncurrentversionExpirationDays != 0 { + return errors.New("non current version Expiration Days cannot be set when transition is being configured") + } + + if params.Body.TransitionDate != "" { + opts = ilm.LifecycleOptions{ + ID: id, + Prefix: params.Body.Prefix, + Status: !params.Body.Disable, + IsTagsSet: params.Body.Tags != "", + IsStorageClassSet: params.Body.StorageClass != "", + Tags: params.Body.Tags, + TransitionDate: params.Body.TransitionDate, + StorageClass: strings.ToUpper(params.Body.StorageClass), + ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker, + NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays), + NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass), + } + } else if params.Body.TransitionDays != 0 { + opts = ilm.LifecycleOptions{ + ID: id, + Prefix: params.Body.Prefix, + Status: !params.Body.Disable, + IsTagsSet: params.Body.Tags != "", + IsStorageClassSet: params.Body.StorageClass != "", + Tags: params.Body.Tags, + TransitionDays: strconv.Itoa(int(params.Body.TransitionDays)), + StorageClass: strings.ToUpper(params.Body.StorageClass), + ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker, + NoncurrentVersionTransitionDays: int(params.Body.NoncurrentversionTransitionDays), + NoncurrentVersionTransitionStorageClass: strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass), + } + } + } else if params.Body.TransitionDate == "" && params.Body.TransitionDays == 0 { + // Verify if expiry items are set + if params.Body.ExpiryDate != "" && params.Body.ExpiryDays != 0 { + return errors.New("only one expiry configuration can be set (days or date)") + } + + if params.Body.TransitionDate != "" || params.Body.TransitionDays != 0 { + return errors.New("transition cannot be set when expiry is being configured") + } + + if params.Body.NoncurrentversionTransitionDays != 0 { + return errors.New("non current version Transition Days cannot be set when expiry is being configured") + } + + if params.Body.NoncurrentversionTransitionStorageClass != "" { + return errors.New("non current version Transition Storage Class cannot be set when expiry is being configured") + } + + if params.Body.ExpiryDate != "" { + opts = ilm.LifecycleOptions{ + ID: id, + Prefix: params.Body.Prefix, + Status: !params.Body.Disable, + IsTagsSet: params.Body.Tags != "", + IsStorageClassSet: params.Body.StorageClass != "", + Tags: params.Body.Tags, + ExpiryDate: params.Body.ExpiryDate, + ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker, + NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays), + } + } else if params.Body.ExpiryDays != 0 { + opts = ilm.LifecycleOptions{ + ID: id, + Prefix: params.Body.Prefix, + Status: !params.Body.Disable, + IsTagsSet: params.Body.Tags != "", + IsStorageClassSet: params.Body.StorageClass != "", + Tags: params.Body.Tags, + ExpiryDays: strconv.Itoa(int(params.Body.ExpiryDays)), + ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker, + NoncurrentVersionExpirationDays: int(params.Body.NoncurrentversionExpirationDays), + } + } + + } else { + // Non set, we return error + return errors.New("no valid configuration is set") + } + + var err2 *probe.Error + lfcCfg, err2 = opts.ToConfig(lfcCfg) + if err2.ToGoError() != nil { + return err2.ToGoError() + } + + return client.setBucketLifecycle(ctx, params.BucketName, lfcCfg) +} + +// getAddBucketLifecycleResponse returns the respose of adding a bucket lifecycle response +func getAddBucketLifecycleResponse(session *models.Principal, params user_api.AddBucketLifecycleParams) *models.Error { + ctx := context.Background() + mClient, err := newMinioClient(session) + if err != nil { + return prepareError(err) + } + // create a minioClient interface implementation + // defining the client to be used + minioClient := minioClient{client: mClient} + + err = addBucketLifecycle(ctx, minioClient, params) + if err != nil { + return prepareError(err) + } + + return nil +} diff --git a/restapi/user_buckets_lifecycle_test.go b/restapi/user_buckets_lifecycle_test.go new file mode 100644 index 0000000000..2344ab123e --- /dev/null +++ b/restapi/user_buckets_lifecycle_test.go @@ -0,0 +1,200 @@ +// 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 . + +package restapi + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/minio/console/models" + "github.com/stretchr/testify/assert" + + "github.com/minio/console/restapi/operations/user_api" + "github.com/minio/minio-go/v7/pkg/lifecycle" +) + +// assigning mock at runtime instead of compile time +var minioGetLifecycleRulesMock func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) + +// mock function of getLifecycleRules() +func (ac minioClientMock) getLifecycleRules(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return minioGetLifecycleRulesMock(ctx, bucketName) +} + +// assign mock for set Bucket Lifecycle +var minioSetBucketLifecycleMock func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error + +// mock function of setBucketLifecycle() +func (ac minioClientMock) setBucketLifecycle(ctx context.Context, bucketName string, config *lifecycle.Configuration) error { + return minioSetBucketLifecycleMock(ctx, bucketName, config) +} + +func TestGetLifecycleRules(t *testing.T) { + assert := assert.New(t) + // mock minIO client + minClient := minioClientMock{} + + function := "getBucketLifecycle()" + bucketName := "testBucket" + ctx := context.Background() + + // Test-1 : getBucketLifecycle() get list of events for a particular bucket only one config + // mock lifecycle response from MinIO + mockLifecycle := lifecycle.Configuration{ + Rules: []lifecycle.Rule{ + { + ID: "TESTRULE", + Expiration: lifecycle.Expiration{Days: 15}, + Status: "Enabled", + RuleFilter: lifecycle.Filter{Tag: lifecycle.Tag{Key: "tag1", Value: "val1"}, And: lifecycle.And{Prefix: "prefix1"}}, + }, + }, + } + + expectedOutput := models.BucketLifecycleResponse{ + Lifecycle: []*models.ObjectBucketLifecycle{ + { + ID: "TESTRULE", + Status: "Enabled", + Prefix: "prefix1", + Expiration: &models.ExpirationResponse{Days: int64(15)}, + Transition: &models.TransitionResponse{}, + Tags: []*models.LifecycleTag{{Key: "tag1", Value: "val1"}}, + }, + }, + } + + minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return &mockLifecycle, nil + } + + lifeCycleConfigs, err := getBucketLifecycle(ctx, minClient, bucketName) + + if err != nil { + t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) + } + // verify length of buckets is correct + assert.Equal(len(expectedOutput.Lifecycle), len(lifeCycleConfigs.Lifecycle), fmt.Sprintf("Failed on %s: length of lists is not the same", function)) + for i, conf := range lifeCycleConfigs.Lifecycle { + assert.Equal(expectedOutput.Lifecycle[i].ID, conf.ID) + assert.Equal(expectedOutput.Lifecycle[i].Status, conf.Status) + assert.Equal(expectedOutput.Lifecycle[i].Prefix, conf.Prefix) + assert.Equal(expectedOutput.Lifecycle[i].Expiration.Days, conf.Expiration.Days) + for j, event := range conf.Tags { + assert.Equal(expectedOutput.Lifecycle[i].Tags[j], event) + } + } + + // Test-2 : getBucketLifecycle() get list of events is empty + mockLifecycleT2 := lifecycle.Configuration{ + Rules: []lifecycle.Rule{}, + } + + expectedOutputT2 := models.BucketLifecycleResponse{ + Lifecycle: []*models.ObjectBucketLifecycle{}, + } + + minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return &mockLifecycleT2, nil + } + + lifeCycleConfigsT2, err := getBucketLifecycle(ctx, minClient, bucketName) + + if err != nil { + t.Errorf("Failed on %s:, error occurred: %s", function, err.Error()) + } + // verify length of buckets is correct + assert.Equal(len(expectedOutputT2.Lifecycle), len(lifeCycleConfigsT2.Lifecycle), fmt.Sprintf("Failed on %s: length of lists is not the same", function)) + + // Test-3 : getBucketLifecycle() get list of events returns an error + + minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return nil, errors.New("error returned") + } + + _, errT3 := getBucketLifecycle(ctx, minClient, bucketName) + + errorCompare := errors.New("error returned") + + assert.Equal(errorCompare, errT3, fmt.Sprintf("Failed on %s: Invalid error message", function)) + + // verify length of buckets is correct + assert.Equal(len(expectedOutputT2.Lifecycle), len(lifeCycleConfigsT2.Lifecycle), fmt.Sprintf("Failed on %s: length of lists is not the same", function)) +} + +func TestSetLifecycleRule(t *testing.T) { + assert := assert.New(t) + // mock minIO client + minClient := minioClientMock{} + + function := "addBucketLifecycle()" + ctx := context.Background() + + // Test-1 : addBucketLifecycle() get list of events for a particular bucket only one config + // mock create request + mockLifecycle := lifecycle.Configuration{ + Rules: []lifecycle.Rule{ + { + ID: "TESTRULE", + Expiration: lifecycle.Expiration{Days: 15}, + Status: "Enabled", + RuleFilter: lifecycle.Filter{Tag: lifecycle.Tag{Key: "tag1", Value: "val1"}, And: lifecycle.And{Prefix: "prefix1"}}, + }, + }, + } + + minioGetLifecycleRulesMock = func(ctx context.Context, bucketName string) (lifecycle *lifecycle.Configuration, err error) { + return &mockLifecycle, nil + } + + insertMock := user_api.AddBucketLifecycleParams{ + BucketName: "testBucket", + Body: &models.AddBucketLifecycle{ + Disable: false, + ExpiredObjectDeleteMarker: false, + ExpiryDays: int32(16), + NoncurrentversionExpirationDays: 0, + NoncurrentversionTransitionDays: 0, + NoncurrentversionTransitionStorageClass: "", + Prefix: "pref1", + StorageClass: "", + Tags: "", + TransitionDate: "", + TransitionDays: 0, + }, + } + + minioSetBucketLifecycleMock = func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error { + return nil + } + + err := addBucketLifecycle(ctx, minClient, insertMock) + + assert.Equal(nil, err, fmt.Sprintf("Failed on %s: Error returned", function)) + + // Test-2 : addBucketLifecycle() returns error + + minioSetBucketLifecycleMock = func(ctx context.Context, bucketName string, config *lifecycle.Configuration) error { + return errors.New("error setting lifecycle") + } + + err2 := addBucketLifecycle(ctx, minClient, insertMock) + + assert.Equal(errors.New("error setting lifecycle"), err2, fmt.Sprintf("Failed on %s: Error returned", function)) +} diff --git a/restapi/user_session.go b/restapi/user_session.go index ceb561ce7a..521006d9c8 100644 --- a/restapi/user_session.go +++ b/restapi/user_session.go @@ -22,6 +22,7 @@ import ( "github.com/minio/console/pkg/acl" "github.com/minio/console/restapi/operations" "github.com/minio/console/restapi/operations/user_api" + "github.com/minio/minio/pkg/env" ) func registerSessionHandlers(api *operations.ConsoleAPI) { @@ -43,8 +44,19 @@ func getSessionResponse(session *models.Principal) (*models.SessionResponse, *mo } sessionResp := &models.SessionResponse{ Pages: acl.GetAuthorizedEndpoints(session.Actions), + Features: getListOfEnabledFeatures(), Status: models.SessionResponseStatusOk, Operator: acl.GetOperatorMode(), } return sessionResp, nil } + +// getListOfEnabledFeatures returns a list of features +func getListOfEnabledFeatures() []string { + var features []string + ilm := env.IsSet("_CONSOLE_ILM_SUPPORT") + if ilm { + features = append(features, "ilm") + } + return features +} diff --git a/swagger.yml b/swagger.yml index 2f78bd399a..feb898988f 100644 --- a/swagger.yml +++ b/swagger.yml @@ -859,6 +859,76 @@ paths: tags: - UserAPI + /buckets/{bucket_name}/lifecycle: + get: + summary: Bucket Lifecycle + operationId: GetBucketLifecycle + parameters: + - name: bucket_name + in: path + required: true + type: string + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/bucketLifecycleResponse" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - UserAPI + post: + summary: Add Bucket Lifecycle + operationId: AddBucketLifecycle + parameters: + - name: bucket_name + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + $ref: "#/definitions/addBucketLifecycle" + responses: + 201: + description: A successful response. + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - UserAPI + /buckets/{bucket_name}/lifecycle/{lifecycle_id}: + put: + summary: Update Lifecycle rule + operationId: UpdateBucketLifecycle + parameters: + - name: bucket_name + in: path + required: true + type: string + - name: lifecycle_id + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + $ref: "#/definitions/updateBucketLifecycle" + responses: + 200: + description: A successful response. + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - UserAPI + /service-accounts: get: summary: List User's Service Accounts @@ -1586,6 +1656,101 @@ paths: tags: - AdminAPI + /admin/tiers: + get: + summary: Returns a list of tiers for ilm + operationId: TiersList + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/tierListResponse" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - AdminAPI + post: + summary: Allows to configure a new tier + operationId: AddTier + parameters: + - name: body + in: body + required: true + schema: + $ref: "#/definitions/tier" + responses: + 201: + description: A successful response. + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - AdminAPI + + /admin/tiers/{type}/{name}: + get: + summary: Get Tier + operationId: GetTier + parameters: + - name: type + in: path + required: true + type: string + enum: + - s3 + - gcs + - azure + - name: name + in: path + required: true + type: string + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/tier" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - AdminAPI + + /admin/tiers/{type}/{name}/credentials: + put: + summary: Edit Tier Credentials + operationId: EditTierCredentials + parameters: + - name: type + in: path + required: true + type: string + enum: + - s3 + - gcs + - azure + - name: name + in: path + required: true + type: string + - name: body + in: body + required: true + schema: + $ref: "#/definitions/tierCredentialsRequest" + responses: + 200: + description: A successful response. + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - AdminAPI + /remote-buckets: get: summary: List Remote Buckets @@ -2658,6 +2823,10 @@ definitions: type: array items: type: string + features: + type: array + items: + type: string status: type: string enum: [ok] @@ -3919,6 +4088,119 @@ definitions: validity: type: integer format: int32 + + bucketLifecycleResponse: + type: object + properties: + lifecycle: + type: array + items: + $ref: "#/definitions/objectBucketLifecycle" + + expirationResponse: + type: object + properties: + date: + type: string + days: + type: integer + format: int64 + delete_marker: + type: boolean + + transitionResponse: + type: object + properties: + date: + type: string + storage_class: + type: string + days: + type: integer + format: int64 + + lifecycleTag: + type: object + properties: + key: + type: string + value: + type: string + + objectBucketLifecycle: + type: object + properties: + id: + type: string + prefix: + type: string + status: + type: string + expiration: + $ref: "#/definitions/expirationResponse" + transition: + $ref: "#/definitions/transitionResponse" + tags: + type: array + items: + $ref: "#/definitions/lifecycleTag" + + + addBucketLifecycle: + type: object + properties: + prefix: + description: Non required field, it matches a prefix to perform ILM operations on it + type: string + tags: + description: Non required field, tags to match ILM files + type: string + expiry_date: + description: Required in case of expiry_days or transition fields are not set. it defines an expiry date for ILM + type: string + expiry_days: + description: Required in case of expiry_date or transition fields are not set. it defines an expiry days for ILM + type: integer + format: int32 + default: 0 + transition_date: + description: Required in case of transition_days or expiry fields are not set. it defines a transition date for ILM + type: string + transition_days: + description: Required in case of transition_date or expiry fields are not set. it defines a transition days for ILM + type: integer + format: int32 + default: 0 + storage_class: + description: Required only in case of transition is set. it refers to a tier + type: string + disable: + description: Non required, toggle to disable or enable rule + type: boolean + expired_object_delete_marker: + description: Non required, toggle to disable or enable rule + type: boolean + noncurrentversion_expiration_days: + description: Non required, can be set in case of expiration is enabled + type: integer + format: int32 + default: 0 + noncurrentversion_transition_days: + description: Non required, can be set in case of transition is enabled + type: integer + format: int32 + default: 0 + noncurrentversion_transition_storage_class: + description: Non required, can be set in case of transition is enabled + type: string + + updateBucketLifecycle: + type: object + properties: + tags: + type: string + disable: + type: boolean setConfigResponse: type: object @@ -3952,3 +4234,96 @@ definitions: type: string expires_at: type: string + + tier_s3: + type: object + properties: + name: + type: string + endpoint: + type: string + accesskey: + type: string + secretkey: + type: string + bucket: + type: string + prefix: + type: string + region: + type: string + storageclass: + type: string + + tier_azure: + type: object + properties: + name: + type: string + endpoint: + type: string + accountname: + type: string + accountkey: + type: string + bucket: + type: string + prefix: + type: string + region: + type: string + + tier_gcs: + type: object + properties: + name: + type: string + endpoint: + type: string + creds: + type: string + bucket: + type: string + prefix: + type: string + region: + type: string + + tier: + type: object + properties: + type: + type: string + enum: + - s3 + - gcs + - azure + - unsupported + s3: + type: object + $ref: "#/definitions/tier_s3" + gcs: + type: object + $ref: "#/definitions/tier_gcs" + azure: + type: object + $ref: "#/definitions/tier_azure" + + tierListResponse: + type: object + properties: + items: + type: array + items: + $ref: "#/definitions/tier" + + tierCredentialsRequest: + type: object + properties: + access_key: + type: string + secret_key: + type: string + creds: + type: string + description: a base64 encoded value