diff --git a/models/add_bucket_lifecycle.go b/models/add_bucket_lifecycle.go
index 41fd06083..dc94d5f08 100644
--- a/models/add_bucket_lifecycle.go
+++ b/models/add_bucket_lifecycle.go
@@ -43,9 +43,6 @@ type AddBucketLifecycle struct {
// 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"`
@@ -67,9 +64,6 @@ type AddBucketLifecycle struct {
// 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"`
diff --git a/models/add_multi_bucket_lifecycle.go b/models/add_multi_bucket_lifecycle.go
new file mode 100644
index 000000000..d636c3213
--- /dev/null
+++ b/models/add_multi_bucket_lifecycle.go
@@ -0,0 +1,168 @@
+// 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 (
+ "context"
+ "encoding/json"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+ "github.com/go-openapi/validate"
+)
+
+// AddMultiBucketLifecycle add multi bucket lifecycle
+//
+// swagger:model addMultiBucketLifecycle
+type AddMultiBucketLifecycle struct {
+
+ // buckets
+ // Required: true
+ Buckets []string `json:"buckets"`
+
+ // Non required, toggle to disable or enable rule
+ ExpiredObjectDeleteMarker bool `json:"expired_object_delete_marker,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_date or expiry fields are not set. it defines a transition days for ILM
+ TransitionDays int32 `json:"transition_days,omitempty"`
+
+ // ILM Rule type (Expiry or transition)
+ // Required: true
+ // Enum: [expiry transition]
+ Type *string `json:"type"`
+}
+
+// Validate validates this add multi bucket lifecycle
+func (m *AddMultiBucketLifecycle) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateBuckets(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 *AddMultiBucketLifecycle) validateBuckets(formats strfmt.Registry) error {
+
+ if err := validate.Required("buckets", "body", m.Buckets); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+var addMultiBucketLifecycleTypeTypePropEnum []interface{}
+
+func init() {
+ var res []string
+ if err := json.Unmarshal([]byte(`["expiry","transition"]`), &res); err != nil {
+ panic(err)
+ }
+ for _, v := range res {
+ addMultiBucketLifecycleTypeTypePropEnum = append(addMultiBucketLifecycleTypeTypePropEnum, v)
+ }
+}
+
+const (
+
+ // AddMultiBucketLifecycleTypeExpiry captures enum value "expiry"
+ AddMultiBucketLifecycleTypeExpiry string = "expiry"
+
+ // AddMultiBucketLifecycleTypeTransition captures enum value "transition"
+ AddMultiBucketLifecycleTypeTransition string = "transition"
+)
+
+// prop value enum
+func (m *AddMultiBucketLifecycle) validateTypeEnum(path, location string, value string) error {
+ if err := validate.EnumCase(path, location, value, addMultiBucketLifecycleTypeTypePropEnum, true); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (m *AddMultiBucketLifecycle) validateType(formats strfmt.Registry) error {
+
+ if err := validate.Required("type", "body", m.Type); err != nil {
+ return err
+ }
+
+ // value enum
+ if err := m.validateTypeEnum("type", "body", *m.Type); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// ContextValidate validates this add multi bucket lifecycle based on context it is used
+func (m *AddMultiBucketLifecycle) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *AddMultiBucketLifecycle) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *AddMultiBucketLifecycle) UnmarshalBinary(b []byte) error {
+ var res AddMultiBucketLifecycle
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/models/multi_lifecycle_result.go b/models/multi_lifecycle_result.go
new file mode 100644
index 000000000..b8fdf98eb
--- /dev/null
+++ b/models/multi_lifecycle_result.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 models
+
+// This file was generated by the swagger tool.
+// Editing this file might prove futile when you re-run the swagger generate command
+
+import (
+ "context"
+ "strconv"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+)
+
+// MultiLifecycleResult multi lifecycle result
+//
+// swagger:model multiLifecycleResult
+type MultiLifecycleResult struct {
+
+ // results
+ Results []*MulticycleResultItem `json:"results"`
+}
+
+// Validate validates this multi lifecycle result
+func (m *MultiLifecycleResult) Validate(formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.validateResults(formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+func (m *MultiLifecycleResult) validateResults(formats strfmt.Registry) error {
+ if swag.IsZero(m.Results) { // not required
+ return nil
+ }
+
+ for i := 0; i < len(m.Results); i++ {
+ if swag.IsZero(m.Results[i]) { // not required
+ continue
+ }
+
+ if m.Results[i] != nil {
+ if err := m.Results[i].Validate(formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("results" + "." + strconv.Itoa(i))
+ } else if ce, ok := err.(*errors.CompositeError); ok {
+ return ce.ValidateName("results" + "." + strconv.Itoa(i))
+ }
+ return err
+ }
+ }
+
+ }
+
+ return nil
+}
+
+// ContextValidate validate this multi lifecycle result based on the context it is used
+func (m *MultiLifecycleResult) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
+ var res []error
+
+ if err := m.contextValidateResults(ctx, formats); err != nil {
+ res = append(res, err)
+ }
+
+ if len(res) > 0 {
+ return errors.CompositeValidationError(res...)
+ }
+ return nil
+}
+
+func (m *MultiLifecycleResult) contextValidateResults(ctx context.Context, formats strfmt.Registry) error {
+
+ for i := 0; i < len(m.Results); i++ {
+
+ if m.Results[i] != nil {
+ if err := m.Results[i].ContextValidate(ctx, formats); err != nil {
+ if ve, ok := err.(*errors.Validation); ok {
+ return ve.ValidateName("results" + "." + strconv.Itoa(i))
+ } else if ce, ok := err.(*errors.CompositeError); ok {
+ return ce.ValidateName("results" + "." + strconv.Itoa(i))
+ }
+ return err
+ }
+ }
+
+ }
+
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *MultiLifecycleResult) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *MultiLifecycleResult) UnmarshalBinary(b []byte) error {
+ var res MultiLifecycleResult
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/models/multicycle_result_item.go b/models/multicycle_result_item.go
new file mode 100644
index 000000000..b0f8472ec
--- /dev/null
+++ b/models/multicycle_result_item.go
@@ -0,0 +1,70 @@
+// 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 (
+ "context"
+
+ "github.com/go-openapi/strfmt"
+ "github.com/go-openapi/swag"
+)
+
+// MulticycleResultItem multicycle result item
+//
+// swagger:model multicycleResultItem
+type MulticycleResultItem struct {
+
+ // bucket name
+ BucketName string `json:"bucketName,omitempty"`
+
+ // error
+ Error string `json:"error,omitempty"`
+}
+
+// Validate validates this multicycle result item
+func (m *MulticycleResultItem) Validate(formats strfmt.Registry) error {
+ return nil
+}
+
+// ContextValidate validates this multicycle result item based on context it is used
+func (m *MulticycleResultItem) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
+ return nil
+}
+
+// MarshalBinary interface implementation
+func (m *MulticycleResultItem) MarshalBinary() ([]byte, error) {
+ if m == nil {
+ return nil, nil
+ }
+ return swag.WriteJSON(m)
+}
+
+// UnmarshalBinary interface implementation
+func (m *MulticycleResultItem) UnmarshalBinary(b []byte) error {
+ var res MulticycleResultItem
+ if err := swag.ReadJSON(b, &res); err != nil {
+ return err
+ }
+ *m = res
+ return nil
+}
diff --git a/portal-ui/src/icons/LifecycleConfigIcon.tsx b/portal-ui/src/icons/LifecycleConfigIcon.tsx
index ce7cbe3dc..7996bcb9f 100644
--- a/portal-ui/src/icons/LifecycleConfigIcon.tsx
+++ b/portal-ui/src/icons/LifecycleConfigIcon.tsx
@@ -20,69 +20,38 @@ import { SVGProps } from "react";
const LifecycleConfigIcon = (props: SVGProps) => (
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
index f00b8fca1..977d754b6 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
@@ -287,6 +287,7 @@ const BucketLifecyclePanel = ({
{!loadingLifecycle && (
+ }
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkLifecycleModal.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkLifecycleModal.tsx
new file mode 100644
index 000000000..27aa194b1
--- /dev/null
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/BulkLifecycleModal.tsx
@@ -0,0 +1,462 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 MinIO, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+import React, { Fragment, useEffect, useState } from "react";
+import { connect } from "react-redux";
+import { Theme } from "@mui/material/styles";
+import createStyles from "@mui/styles/createStyles";
+import withStyles from "@mui/styles/withStyles";
+import { SelectChangeEvent, Tooltip } from "@mui/material";
+import get from "lodash/get";
+import Grid from "@mui/material/Grid";
+import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
+import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
+import {
+ createTenantCommon,
+ formFieldStyles,
+ modalStyleUtils,
+ spacingUtils,
+} from "../../Common/FormComponents/common/styleLibrary";
+import { setModalErrorSnackMessage } from "../../../../actions";
+import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
+import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
+import PredefinedList from "../../Common/FormComponents/PredefinedList/PredefinedList";
+import api from "../../../../common/api";
+import GenericWizard from "../../Common/GenericWizard/GenericWizard";
+import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
+import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
+import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
+import { ErrorResponseHandler } from "../../../../common/types";
+import QueryMultiSelector from "../../Common/FormComponents/QueryMultiSelector/QueryMultiSelector";
+import { ITiersDropDown } from "../BucketDetails/AddLifecycleModal";
+import {
+ ITierElement,
+ ITierResponse,
+} from "../../Configurations/TiersConfiguration/types";
+import { MultiBucketResult } from "../types";
+
+interface IBulkReplicationModal {
+ open: boolean;
+ closeModalAndRefresh: (clearSelection: boolean) => any;
+ classes: any;
+ buckets: string[];
+ setModalErrorSnackMessage: typeof setModalErrorSnackMessage;
+}
+
+const styles = (theme: Theme) =>
+ createStyles({
+ resultGrid: {
+ display: "grid",
+ gridTemplateColumns: "45px auto",
+ alignItems: "center",
+ justifyContent: "stretch",
+ },
+ errorIcon: {
+ paddingTop: 5,
+ color: "#C72C48",
+ },
+ successIcon: {
+ paddingTop: 5,
+ color: "#42C91A",
+ },
+ hide: {
+ opacity: 0,
+ transitionDuration: "0.3s",
+ },
+ ...spacingUtils,
+ ...modalStyleUtils,
+ ...formFieldStyles,
+ ...createTenantCommon,
+ });
+
+const AddBulkReplicationModal = ({
+ open,
+ closeModalAndRefresh,
+ classes,
+ buckets,
+ setModalErrorSnackMessage,
+}: IBulkReplicationModal) => {
+ const [addLoading, setAddLoading] = useState(false);
+ const [loadingTiers, setLoadingTiers] = useState(true);
+ const [tiersList, setTiersList] = useState([]);
+ 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 [expiryDays, setExpiryDays] = useState("0");
+ const [transitionDays, setTransitionDays] = useState("0");
+ const [isFormValid, setIsFormValid] = useState(false);
+ const [results, setResults] = useState(null);
+
+ 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: ErrorResponseHandler) => {
+ setLoadingTiers(false);
+ setModalErrorSnackMessage(err);
+ });
+ }
+ }, [loadingTiers, setModalErrorSnackMessage]);
+
+ useEffect(() => {
+ let valid = true;
+
+ if (ilmType !== "expiry") {
+ if (storageClass === "") {
+ valid = false;
+ }
+ }
+ setIsFormValid(valid);
+ }, [ilmType, expiryDays, transitionDays, storageClass]);
+
+ const LogoToShow = ({ errString }: { errString: string }) => {
+ switch (errString) {
+ case "":
+ return (
+
+
+
+ );
+ case "n/a":
+ return null;
+ default:
+ if (errString) {
+ return (
+
+ );
+ })}
+
+
+
+ ),
+ buttons: [
+ {
+ type: "custom",
+ label: "Done",
+ enabled: !addLoading,
+ action: () => closeModalAndRefresh(true),
+ },
+ ],
+ },
+ ]}
+ forModal
+ />
+
+ );
+};
+
+const connector = connect(null, {
+ setModalErrorSnackMessage,
+});
+
+export default withStyles(styles)(connector(AddBulkReplicationModal));
diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
index fcc21cc1e..18b95551f 100644
--- a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
+++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx
@@ -22,7 +22,7 @@ import withStyles from "@mui/styles/withStyles";
import { LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import { Bucket, BucketList } from "../types";
-import { AddIcon, BucketsIcon } from "../../../../icons";
+import {AddIcon, BucketsIcon, LifecycleConfigIcon} from "../../../../icons";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import {
@@ -50,6 +50,7 @@ import PageLayout from "../../Common/Layout/PageLayout";
import SearchBox from "../../Common/SearchBox";
import VirtualizedList from "../../Common/VirtualizedList/VirtualizedList";
import RBIconButton from "../BucketDetails/SummaryItems/RBIconButton";
+import BulkLifecycleModal from "./BulkLifecycleModal";
const styles = (theme: Theme) =>
createStyles({
@@ -100,6 +101,7 @@ const ListBuckets = ({
const [selectedBuckets, setSelectedBuckets] = useState([]);
const [replicationModalOpen, setReplicationModalOpen] =
useState(false);
+ const [lifecycleModalOpen, setLifecycleModalOpen] = useState(false);
const [bulkSelect, setBulkSelect] = useState(false);
@@ -174,6 +176,14 @@ const ListBuckets = ({
}
};
+ const closeBulkLifecycleModal = (unselectAll: boolean) => {
+ setLifecycleModalOpen(false);
+
+ if (unselectAll) {
+ setSelectedBuckets([]);
+ }
+ };
+
const renderItemLine = (index: number) => {
const bucket = filteredRecords[index] || null;
if (bucket) {
@@ -213,6 +223,13 @@ const ListBuckets = ({
closeModalAndRefresh={closeBulkReplicationModal}
/>
)}
+ {lifecycleModalOpen && (
+
+ )}
@@ -241,6 +258,18 @@ const ListBuckets = ({
variant={bulkSelect ? "contained" : "outlined"}
/>
+ {
+ setLifecycleModalOpen(true);
+ }}
+ text={""}
+ icon={}
+ disabled={selectedBuckets.length === 0}
+ color={"primary"}
+ variant={"outlined"}
+ />
+
{
diff --git a/portal-ui/src/screens/Console/Buckets/types.tsx b/portal-ui/src/screens/Console/Buckets/types.tsx
index 18ff88e2d..0d2b26747 100644
--- a/portal-ui/src/screens/Console/Buckets/types.tsx
+++ b/portal-ui/src/screens/Console/Buckets/types.tsx
@@ -201,3 +201,12 @@ export interface LifeCycleItem {
tags?: any;
status?: string;
}
+
+export interface MultiBucketResult {
+ bucketName: string,
+ error?: string,
+}
+
+export interface MultiBucketResult {
+ results: MultiBucketResult[],
+}
diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go
index de55fc6d3..ea1e9a33e 100644
--- a/restapi/embedded_spec.go
+++ b/restapi/embedded_spec.go
@@ -698,6 +698,39 @@ func init() {
}
}
},
+ "/buckets/multi-lifecycle": {
+ "post": {
+ "tags": [
+ "UserAPI"
+ ],
+ "summary": "Add Multi Bucket Lifecycle",
+ "operationId": "AddMultiBucketLifecycle",
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/addMultiBucketLifecycle"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/multiLifecycleResult"
+ }
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
"/buckets/{bucket_name}/delete-objects": {
"post": {
"tags": [
@@ -3850,10 +3883,6 @@ func init() {
"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",
@@ -3888,10 +3917,6 @@ func init() {
"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",
@@ -3937,6 +3962,73 @@ func init() {
}
}
},
+ "addMultiBucketLifecycle": {
+ "type": "object",
+ "required": [
+ "buckets",
+ "type"
+ ],
+ "properties": {
+ "buckets": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "expired_object_delete_marker": {
+ "description": "Non required, toggle to disable or enable rule",
+ "type": "boolean"
+ },
+ "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_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
+ },
+ "type": {
+ "description": "ILM Rule type (Expiry or transition)",
+ "type": "string",
+ "enum": [
+ "expiry",
+ "transition"
+ ]
+ }
+ }
+ },
"addPolicyRequest": {
"type": "object",
"required": [
@@ -5043,6 +5135,27 @@ func init() {
}
}
},
+ "multiLifecycleResult": {
+ "properties": {
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/multicycleResultItem"
+ }
+ }
+ }
+ },
+ "multicycleResultItem": {
+ "type": "object",
+ "properties": {
+ "bucketName": {
+ "type": "string"
+ },
+ "error": {
+ "type": "string"
+ }
+ }
+ },
"nofiticationService": {
"type": "string",
"enum": [
@@ -6956,6 +7069,39 @@ func init() {
}
}
},
+ "/buckets/multi-lifecycle": {
+ "post": {
+ "tags": [
+ "UserAPI"
+ ],
+ "summary": "Add Multi Bucket Lifecycle",
+ "operationId": "AddMultiBucketLifecycle",
+ "parameters": [
+ {
+ "name": "body",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/addMultiBucketLifecycle"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/multiLifecycleResult"
+ }
+ },
+ "default": {
+ "description": "Generic error response.",
+ "schema": {
+ "$ref": "#/definitions/error"
+ }
+ }
+ }
+ }
+ },
"/buckets/{bucket_name}/delete-objects": {
"post": {
"tags": [
@@ -10226,10 +10372,6 @@ func init() {
"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",
@@ -10264,10 +10406,6 @@ func init() {
"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",
@@ -10313,6 +10451,73 @@ func init() {
}
}
},
+ "addMultiBucketLifecycle": {
+ "type": "object",
+ "required": [
+ "buckets",
+ "type"
+ ],
+ "properties": {
+ "buckets": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "expired_object_delete_marker": {
+ "description": "Non required, toggle to disable or enable rule",
+ "type": "boolean"
+ },
+ "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_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
+ },
+ "type": {
+ "description": "ILM Rule type (Expiry or transition)",
+ "type": "string",
+ "enum": [
+ "expiry",
+ "transition"
+ ]
+ }
+ }
+ },
"addPolicyRequest": {
"type": "object",
"required": [
@@ -11419,6 +11624,27 @@ func init() {
}
}
},
+ "multiLifecycleResult": {
+ "properties": {
+ "results": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/multicycleResultItem"
+ }
+ }
+ }
+ },
+ "multicycleResultItem": {
+ "type": "object",
+ "properties": {
+ "bucketName": {
+ "type": "string"
+ },
+ "error": {
+ "type": "string"
+ }
+ }
+ },
"nofiticationService": {
"type": "string",
"enum": [
diff --git a/restapi/operations/console_api.go b/restapi/operations/console_api.go
index 535936a8b..e5e077344 100644
--- a/restapi/operations/console_api.go
+++ b/restapi/operations/console_api.go
@@ -74,6 +74,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
AdminAPIAddGroupHandler: admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.AddGroup has not yet been implemented")
}),
+ UserAPIAddMultiBucketLifecycleHandler: user_api.AddMultiBucketLifecycleHandlerFunc(func(params user_api.AddMultiBucketLifecycleParams, principal *models.Principal) middleware.Responder {
+ return middleware.NotImplemented("operation user_api.AddMultiBucketLifecycle has not yet been implemented")
+ }),
AdminAPIAddNotificationEndpointHandler: admin_api.AddNotificationEndpointHandlerFunc(func(params admin_api.AddNotificationEndpointParams, principal *models.Principal) middleware.Responder {
return middleware.NotImplemented("operation admin_api.AddNotificationEndpoint has not yet been implemented")
}),
@@ -456,6 +459,8 @@ type ConsoleAPI struct {
UserAPIAddBucketLifecycleHandler user_api.AddBucketLifecycleHandler
// AdminAPIAddGroupHandler sets the operation handler for the add group operation
AdminAPIAddGroupHandler admin_api.AddGroupHandler
+ // UserAPIAddMultiBucketLifecycleHandler sets the operation handler for the add multi bucket lifecycle operation
+ UserAPIAddMultiBucketLifecycleHandler user_api.AddMultiBucketLifecycleHandler
// AdminAPIAddNotificationEndpointHandler sets the operation handler for the add notification endpoint operation
AdminAPIAddNotificationEndpointHandler admin_api.AddNotificationEndpointHandler
// AdminAPIAddPolicyHandler sets the operation handler for the add policy operation
@@ -766,6 +771,9 @@ func (o *ConsoleAPI) Validate() error {
if o.AdminAPIAddGroupHandler == nil {
unregistered = append(unregistered, "admin_api.AddGroupHandler")
}
+ if o.UserAPIAddMultiBucketLifecycleHandler == nil {
+ unregistered = append(unregistered, "user_api.AddMultiBucketLifecycleHandler")
+ }
if o.AdminAPIAddNotificationEndpointHandler == nil {
unregistered = append(unregistered, "admin_api.AddNotificationEndpointHandler")
}
@@ -1204,6 +1212,10 @@ func (o *ConsoleAPI) initHandlerCache() {
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
}
+ o.handlers["POST"]["/buckets/multi-lifecycle"] = user_api.NewAddMultiBucketLifecycle(o.context, o.UserAPIAddMultiBucketLifecycleHandler)
+ if o.handlers["POST"] == nil {
+ o.handlers["POST"] = make(map[string]http.Handler)
+ }
o.handlers["POST"]["/admin/notification_endpoints"] = admin_api.NewAddNotificationEndpoint(o.context, o.AdminAPIAddNotificationEndpointHandler)
if o.handlers["POST"] == nil {
o.handlers["POST"] = make(map[string]http.Handler)
diff --git a/restapi/operations/user_api/add_multi_bucket_lifecycle.go b/restapi/operations/user_api/add_multi_bucket_lifecycle.go
new file mode 100644
index 000000000..623a36bd9
--- /dev/null
+++ b/restapi/operations/user_api/add_multi_bucket_lifecycle.go
@@ -0,0 +1,88 @@
+// 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"
+)
+
+// AddMultiBucketLifecycleHandlerFunc turns a function with the right signature into a add multi bucket lifecycle handler
+type AddMultiBucketLifecycleHandlerFunc func(AddMultiBucketLifecycleParams, *models.Principal) middleware.Responder
+
+// Handle executing the request and returning a response
+func (fn AddMultiBucketLifecycleHandlerFunc) Handle(params AddMultiBucketLifecycleParams, principal *models.Principal) middleware.Responder {
+ return fn(params, principal)
+}
+
+// AddMultiBucketLifecycleHandler interface for that can handle valid add multi bucket lifecycle params
+type AddMultiBucketLifecycleHandler interface {
+ Handle(AddMultiBucketLifecycleParams, *models.Principal) middleware.Responder
+}
+
+// NewAddMultiBucketLifecycle creates a new http.Handler for the add multi bucket lifecycle operation
+func NewAddMultiBucketLifecycle(ctx *middleware.Context, handler AddMultiBucketLifecycleHandler) *AddMultiBucketLifecycle {
+ return &AddMultiBucketLifecycle{Context: ctx, Handler: handler}
+}
+
+/* AddMultiBucketLifecycle swagger:route POST /buckets/multi-lifecycle UserAPI addMultiBucketLifecycle
+
+Add Multi Bucket Lifecycle
+
+*/
+type AddMultiBucketLifecycle struct {
+ Context *middleware.Context
+ Handler AddMultiBucketLifecycleHandler
+}
+
+func (o *AddMultiBucketLifecycle) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+ route, rCtx, _ := o.Context.RouteInfo(r)
+ if rCtx != nil {
+ *r = *rCtx
+ }
+ var Params = NewAddMultiBucketLifecycleParams()
+ 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_multi_bucket_lifecycle_parameters.go b/restapi/operations/user_api/add_multi_bucket_lifecycle_parameters.go
new file mode 100644
index 000000000..89e034212
--- /dev/null
+++ b/restapi/operations/user_api/add_multi_bucket_lifecycle_parameters.go
@@ -0,0 +1,102 @@
+// 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 (
+ "context"
+ "io"
+ "net/http"
+
+ "github.com/go-openapi/errors"
+ "github.com/go-openapi/runtime"
+ "github.com/go-openapi/runtime/middleware"
+ "github.com/go-openapi/validate"
+
+ "github.com/minio/console/models"
+)
+
+// NewAddMultiBucketLifecycleParams creates a new AddMultiBucketLifecycleParams object
+//
+// There are no default values defined in the spec.
+func NewAddMultiBucketLifecycleParams() AddMultiBucketLifecycleParams {
+
+ return AddMultiBucketLifecycleParams{}
+}
+
+// AddMultiBucketLifecycleParams contains all the bound params for the add multi bucket lifecycle operation
+// typically these are obtained from a http.Request
+//
+// swagger:parameters AddMultiBucketLifecycle
+type AddMultiBucketLifecycleParams struct {
+
+ // HTTP Request Object
+ HTTPRequest *http.Request `json:"-"`
+
+ /*
+ Required: true
+ In: body
+ */
+ Body *models.AddMultiBucketLifecycle
+}
+
+// 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 NewAddMultiBucketLifecycleParams() beforehand.
+func (o *AddMultiBucketLifecycleParams) 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.AddMultiBucketLifecycle
+ 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)
+ }
+
+ ctx := validate.WithOperationRequest(context.Background())
+ if err := body.ContextValidate(ctx, 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/user_api/add_multi_bucket_lifecycle_responses.go b/restapi/operations/user_api/add_multi_bucket_lifecycle_responses.go
new file mode 100644
index 000000000..2eff03ed3
--- /dev/null
+++ b/restapi/operations/user_api/add_multi_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"
+)
+
+// AddMultiBucketLifecycleOKCode is the HTTP code returned for type AddMultiBucketLifecycleOK
+const AddMultiBucketLifecycleOKCode int = 200
+
+/*AddMultiBucketLifecycleOK A successful response.
+
+swagger:response addMultiBucketLifecycleOK
+*/
+type AddMultiBucketLifecycleOK struct {
+
+ /*
+ In: Body
+ */
+ Payload *models.MultiLifecycleResult `json:"body,omitempty"`
+}
+
+// NewAddMultiBucketLifecycleOK creates AddMultiBucketLifecycleOK with default headers values
+func NewAddMultiBucketLifecycleOK() *AddMultiBucketLifecycleOK {
+
+ return &AddMultiBucketLifecycleOK{}
+}
+
+// WithPayload adds the payload to the add multi bucket lifecycle o k response
+func (o *AddMultiBucketLifecycleOK) WithPayload(payload *models.MultiLifecycleResult) *AddMultiBucketLifecycleOK {
+ o.Payload = payload
+ return o
+}
+
+// SetPayload sets the payload to the add multi bucket lifecycle o k response
+func (o *AddMultiBucketLifecycleOK) SetPayload(payload *models.MultiLifecycleResult) {
+ o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *AddMultiBucketLifecycleOK) 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
+ }
+ }
+}
+
+/*AddMultiBucketLifecycleDefault Generic error response.
+
+swagger:response addMultiBucketLifecycleDefault
+*/
+type AddMultiBucketLifecycleDefault struct {
+ _statusCode int
+
+ /*
+ In: Body
+ */
+ Payload *models.Error `json:"body,omitempty"`
+}
+
+// NewAddMultiBucketLifecycleDefault creates AddMultiBucketLifecycleDefault with default headers values
+func NewAddMultiBucketLifecycleDefault(code int) *AddMultiBucketLifecycleDefault {
+ if code <= 0 {
+ code = 500
+ }
+
+ return &AddMultiBucketLifecycleDefault{
+ _statusCode: code,
+ }
+}
+
+// WithStatusCode adds the status to the add multi bucket lifecycle default response
+func (o *AddMultiBucketLifecycleDefault) WithStatusCode(code int) *AddMultiBucketLifecycleDefault {
+ o._statusCode = code
+ return o
+}
+
+// SetStatusCode sets the status to the add multi bucket lifecycle default response
+func (o *AddMultiBucketLifecycleDefault) SetStatusCode(code int) {
+ o._statusCode = code
+}
+
+// WithPayload adds the payload to the add multi bucket lifecycle default response
+func (o *AddMultiBucketLifecycleDefault) WithPayload(payload *models.Error) *AddMultiBucketLifecycleDefault {
+ o.Payload = payload
+ return o
+}
+
+// SetPayload sets the payload to the add multi bucket lifecycle default response
+func (o *AddMultiBucketLifecycleDefault) SetPayload(payload *models.Error) {
+ o.Payload = payload
+}
+
+// WriteResponse to the client
+func (o *AddMultiBucketLifecycleDefault) 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_multi_bucket_lifecycle_urlbuilder.go b/restapi/operations/user_api/add_multi_bucket_lifecycle_urlbuilder.go
new file mode 100644
index 000000000..422095418
--- /dev/null
+++ b/restapi/operations/user_api/add_multi_bucket_lifecycle_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 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"
+)
+
+// AddMultiBucketLifecycleURL generates an URL for the add multi bucket lifecycle operation
+type AddMultiBucketLifecycleURL 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 *AddMultiBucketLifecycleURL) WithBasePath(bp string) *AddMultiBucketLifecycleURL {
+ 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 *AddMultiBucketLifecycleURL) SetBasePath(bp string) {
+ o._basePath = bp
+}
+
+// Build a url path and query string
+func (o *AddMultiBucketLifecycleURL) Build() (*url.URL, error) {
+ var _result url.URL
+
+ var _path = "/buckets/multi-lifecycle"
+
+ _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 *AddMultiBucketLifecycleURL) 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 *AddMultiBucketLifecycleURL) String() string {
+ return o.Must(o.Build()).String()
+}
+
+// BuildFull builds a full url with scheme, host, path and query string
+func (o *AddMultiBucketLifecycleURL) BuildFull(scheme, host string) (*url.URL, error) {
+ if scheme == "" {
+ return nil, errors.New("scheme is required for a full url on AddMultiBucketLifecycleURL")
+ }
+ if host == "" {
+ return nil, errors.New("host is required for a full url on AddMultiBucketLifecycleURL")
+ }
+
+ 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 *AddMultiBucketLifecycleURL) 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
index e480c6016..f7403004b 100644
--- a/restapi/user_buckets_lifecycle.go
+++ b/restapi/user_buckets_lifecycle.go
@@ -39,6 +39,11 @@ import (
"github.com/minio/console/restapi/operations/user_api"
)
+type MultiLifecycleResult struct {
+ BucketName string
+ Error string
+}
+
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)
@@ -70,6 +75,14 @@ func registerBucketsLifecycleHandlers(api *operations.ConsoleAPI) {
return user_api.NewDeleteBucketLifecycleRuleNoContent()
})
+ api.UserAPIAddMultiBucketLifecycleHandler = user_api.AddMultiBucketLifecycleHandlerFunc(func(params user_api.AddMultiBucketLifecycleParams, session *models.Principal) middleware.Responder {
+ multiBucketResponse, err := getAddMultiBucketLifecycleResponse(session, params)
+ if err != nil {
+ user_api.NewAddMultiBucketLifecycleDefault(int(err.Code)).WithPayload(err)
+ }
+
+ return user_api.NewAddMultiBucketLifecycleOK().WithPayload(multiBucketResponse)
+ })
}
// getBucketLifecycle() gets lifecycle lists for a bucket from MinIO API and returns their implementations
@@ -376,3 +389,98 @@ func getDeleteBucketLifecycleRule(session *models.Principal, params user_api.Del
return nil
}
+
+// addMultiBucketLifecycle creates multibuckets lifecycle assignments
+func addMultiBucketLifecycle(ctx context.Context, client MinioClient, params user_api.AddMultiBucketLifecycleParams) []MultiLifecycleResult {
+ bucketsRelation := params.Body.Buckets
+
+ // Parallel Lifecycle rules set
+
+ parallelLifecycleBucket := func(bucketName string) chan MultiLifecycleResult {
+ remoteProc := make(chan MultiLifecycleResult)
+
+ lifecycleParams := models.AddBucketLifecycle{
+ Type: *params.Body.Type,
+ StorageClass: params.Body.StorageClass,
+ TransitionDays: params.Body.TransitionDays,
+ Prefix: params.Body.Prefix,
+ NoncurrentversionTransitionDays: params.Body.NoncurrentversionTransitionDays,
+ NoncurrentversionTransitionStorageClass: params.Body.NoncurrentversionTransitionStorageClass,
+ NoncurrentversionExpirationDays: params.Body.NoncurrentversionExpirationDays,
+ Tags: params.Body.Tags,
+ ExpiryDays: params.Body.ExpiryDays,
+ Disable: false,
+ ExpiredObjectDeleteMarker: params.Body.ExpiredObjectDeleteMarker,
+ }
+
+ go func() {
+ defer close(remoteProc)
+
+ lifecycleParams := user_api.AddBucketLifecycleParams{
+ BucketName: bucketName,
+ Body: &lifecycleParams,
+ }
+
+ // We add lifecycle rule & expect a response
+ err := addBucketLifecycle(ctx, client, lifecycleParams)
+
+ var errorReturn = ""
+
+ if err != nil {
+ errorReturn = err.Error()
+ }
+
+ retParams := MultiLifecycleResult{
+ BucketName: bucketName,
+ Error: errorReturn,
+ }
+
+ remoteProc <- retParams
+ }()
+ return remoteProc
+ }
+
+ var lifecycleManagement []chan MultiLifecycleResult
+
+ for _, bucketName := range bucketsRelation {
+ rBucket := parallelLifecycleBucket(bucketName)
+ lifecycleManagement = append(lifecycleManagement, rBucket)
+ }
+
+ var resultsList []MultiLifecycleResult
+ for _, result := range lifecycleManagement {
+ res := <-result
+ resultsList = append(resultsList, res)
+ }
+
+ return resultsList
+}
+
+// getAddMultiBucketLifecycleResponse returns the response of multibucket lifecycle assignment
+func getAddMultiBucketLifecycleResponse(session *models.Principal, params user_api.AddMultiBucketLifecycleParams) (*models.MultiLifecycleResult, *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}
+
+ multiCycleResult := addMultiBucketLifecycle(ctx, minioClient, params)
+
+ var returnList []*models.MulticycleResultItem
+
+ for _, resultItem := range multiCycleResult {
+ multicycleRS := models.MulticycleResultItem{
+ BucketName: resultItem.BucketName,
+ Error: resultItem.Error,
+ }
+
+ returnList = append(returnList, &multicycleRS)
+ }
+
+ finalResult := models.MultiLifecycleResult{Results: returnList}
+
+ return &finalResult, nil
+}
diff --git a/restapi/user_buckets_lifecycle_test.go b/restapi/user_buckets_lifecycle_test.go
index 6326c8305..66ffda317 100644
--- a/restapi/user_buckets_lifecycle_test.go
+++ b/restapi/user_buckets_lifecycle_test.go
@@ -178,7 +178,6 @@ func TestSetLifecycleRule(t *testing.T) {
Prefix: "pref1",
StorageClass: "",
Tags: "",
- TransitionDate: "",
TransitionDays: 0,
},
}
diff --git a/swagger-console.yml b/swagger-console.yml
index 9ea62117a..d0087dce9 100644
--- a/swagger-console.yml
+++ b/swagger-console.yml
@@ -1115,6 +1115,28 @@ paths:
tags:
- UserAPI
+ /buckets/multi-lifecycle:
+ post:
+ summary: Add Multi Bucket Lifecycle
+ operationId: AddMultiBucketLifecycle
+ parameters:
+ - name: body
+ in: body
+ required: true
+ schema:
+ $ref: "#/definitions/addMultiBucketLifecycle"
+ responses:
+ 200:
+ description: A successful response.
+ schema:
+ $ref: "#/definitions/multiLifecycleResult"
+ default:
+ description: Generic error response.
+ schema:
+ $ref: "#/definitions/error"
+ tags:
+ - UserAPI
+
/buckets/{bucket_name}/lifecycle/{lifecycle_id}:
put:
summary: Update Lifecycle rule
@@ -3931,17 +3953,11 @@ definitions:
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
@@ -4020,6 +4036,73 @@ definitions:
description: Non required, can be set in case of transition is enabled
type: string
+ addMultiBucketLifecycle:
+ type: object
+ required:
+ - buckets
+ - type
+ properties:
+ buckets:
+ type: array
+ items:
+ type: string
+ type:
+ description: ILM Rule type (Expiry or transition)
+ type: string
+ enum:
+ - expiry
+ - transition
+ 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_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_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
+ 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
+
+ multicycleResultItem:
+ type: object
+ properties:
+ bucketName:
+ type: string
+ error:
+ type: string
+
+ multiLifecycleResult:
+ properties:
+ results:
+ type: array
+ items:
+ $ref: "#/definitions/multicycleResultItem"
+
prefixAccessPair:
type: object
properties: