Add UI to select number of non-current versions subject to ILM expiry rule (#3088)
This commit is contained in:
@@ -46,6 +46,9 @@ type AddBucketLifecycle struct {
|
||||
// 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
|
||||
NewerNoncurrentversionExpirationVersions int32 `json:"newer_noncurrentversion_expiration_versions,omitempty"`
|
||||
|
||||
// Non required, can be set in case of expiration is enabled
|
||||
NoncurrentversionExpirationDays int32 `json:"noncurrentversion_expiration_days,omitempty"`
|
||||
|
||||
|
||||
@@ -43,6 +43,9 @@ type ExpirationResponse struct {
|
||||
// delete marker
|
||||
DeleteMarker bool `json:"delete_marker,omitempty"`
|
||||
|
||||
// newer noncurrent expiration versions
|
||||
NewerNoncurrentExpirationVersions int64 `json:"newer_noncurrent_expiration_versions,omitempty"`
|
||||
|
||||
// noncurrent expiration days
|
||||
NoncurrentExpirationDays int64 `json:"noncurrent_expiration_days,omitempty"`
|
||||
}
|
||||
|
||||
@@ -880,6 +880,8 @@ export interface ExpirationResponse {
|
||||
delete_marker?: boolean;
|
||||
/** @format int64 */
|
||||
noncurrent_expiration_days?: number;
|
||||
/** @format int64 */
|
||||
newer_noncurrent_expiration_versions?: number;
|
||||
}
|
||||
|
||||
export interface TransitionResponse {
|
||||
@@ -943,6 +945,12 @@ export interface AddBucketLifecycle {
|
||||
* @default 0
|
||||
*/
|
||||
noncurrentversion_transition_days?: number;
|
||||
/**
|
||||
* Non required, can be set in case of expiration is enabled
|
||||
* @format int32
|
||||
* @default 0
|
||||
*/
|
||||
newer_noncurrentversion_expiration_versions?: number;
|
||||
/** Non required, can be set in case of transition is enabled */
|
||||
noncurrentversion_transition_storage_class?: string;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,11 @@ import React, { Fragment, useEffect, useState } from "react";
|
||||
import get from "lodash/get";
|
||||
import {
|
||||
Accordion,
|
||||
AlertIcon,
|
||||
Button,
|
||||
FormLayout,
|
||||
Grid,
|
||||
HelpTip,
|
||||
InputBox,
|
||||
LifecycleConfigIcon,
|
||||
ProgressBar,
|
||||
@@ -74,6 +76,7 @@ const AddLifecycleModal = ({
|
||||
const [loadingVersioning, setLoadingVersioning] = useState<boolean>(true);
|
||||
const [expandedAdv, setExpandedAdv] = useState<boolean>(false);
|
||||
const [expanded, setExpanded] = useState<boolean>(false);
|
||||
const [expiryUnit, setExpiryUnit] = useState<string>("days");
|
||||
|
||||
/*To be removed on component replacement*/
|
||||
const formFieldRowFilter = {
|
||||
@@ -116,6 +119,13 @@ const AddLifecycleModal = ({
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (!lifecycleDays || parseInt(lifecycleDays) === 0) {
|
||||
valid = false;
|
||||
}
|
||||
if (parseInt(lifecycleDays) > 2147483647) {
|
||||
//values over int32 cannot be parsed
|
||||
valid = false;
|
||||
}
|
||||
setIsFormValid(valid);
|
||||
}, [ilmType, lifecycleDays, storageClass]);
|
||||
|
||||
@@ -142,8 +152,11 @@ const AddLifecycleModal = ({
|
||||
|
||||
if (targetVersion === "current") {
|
||||
expiry["expiry_days"] = parseInt(lifecycleDays);
|
||||
} else {
|
||||
} else if (expiryUnit === "days") {
|
||||
expiry["noncurrentversion_expiration_days"] = parseInt(lifecycleDays);
|
||||
} else {
|
||||
expiry["newer_noncurrentversion_expiration_versions"] =
|
||||
parseInt(lifecycleDays);
|
||||
}
|
||||
|
||||
rules = {
|
||||
@@ -154,7 +167,7 @@ const AddLifecycleModal = ({
|
||||
if (targetVersion === "current") {
|
||||
transition["transition_days"] = parseInt(lifecycleDays);
|
||||
transition["storage_class"] = storageClass;
|
||||
} else {
|
||||
} else if (expiryUnit === "days") {
|
||||
transition["noncurrentversion_transition_days"] =
|
||||
parseInt(lifecycleDays);
|
||||
transition["noncurrentversion_transition_storage_class"] = storageClass;
|
||||
@@ -184,7 +197,6 @@ const AddLifecycleModal = ({
|
||||
dispatch(setModalErrorSnackMessage(errorToHandler(err)));
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
@@ -284,6 +296,15 @@ const AddLifecycleModal = ({
|
||||
)}
|
||||
|
||||
<InputBox
|
||||
error={
|
||||
lifecycleDays && !isFormValid
|
||||
? parseInt(lifecycleDays) <= 0
|
||||
? `Number of ${expiryUnit} to retain must be greater than zero`
|
||||
: parseInt(lifecycleDays) > 2147483647
|
||||
? `Number of ${expiryUnit} must be less than or equal to 2147483647`
|
||||
: ""
|
||||
: ""
|
||||
}
|
||||
id="expiry_days"
|
||||
name="expiry_days"
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -295,12 +316,38 @@ const AddLifecycleModal = ({
|
||||
label="After"
|
||||
value={lifecycleDays}
|
||||
overlayObject={
|
||||
<InputUnitMenu
|
||||
id={"expire-current-unit"}
|
||||
unitSelected={"days"}
|
||||
unitsList={[{ label: "Days", value: "days" }]}
|
||||
disabled={true}
|
||||
/>
|
||||
<Fragment>
|
||||
<Grid container sx={{ justifyContent: "center" }}>
|
||||
<InputUnitMenu
|
||||
id={"expire-current-unit"}
|
||||
unitSelected={expiryUnit}
|
||||
unitsList={[
|
||||
{ label: "Days", value: "days" },
|
||||
{ label: "Versions", value: "versions" },
|
||||
]}
|
||||
disabled={
|
||||
targetVersion !== "noncurrent" || ilmType !== "expiry"
|
||||
}
|
||||
onUnitChange={(newValue) => {
|
||||
setExpiryUnit(newValue);
|
||||
}}
|
||||
/>
|
||||
{ilmType === "expiry" && targetVersion === "noncurrent" && (
|
||||
<HelpTip
|
||||
content={
|
||||
<Fragment>
|
||||
Select to set expiry by days or newer noncurrent
|
||||
versions
|
||||
</Fragment>
|
||||
}
|
||||
placement="right"
|
||||
>
|
||||
{" "}
|
||||
<AlertIcon style={{ width: 15, height: 15 }} />
|
||||
</HelpTip>
|
||||
)}
|
||||
</Grid>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
|
||||
|
||||
@@ -86,7 +86,6 @@ const BucketLifecyclePanel = () => {
|
||||
.getBucketLifecycle(bucketName)
|
||||
.then((res) => {
|
||||
const records = get(res.data, "lifecycle", []);
|
||||
|
||||
setLifecycleRecords(records || []);
|
||||
setLoadingLifecycle(false);
|
||||
})
|
||||
@@ -147,7 +146,10 @@ const BucketLifecyclePanel = () => {
|
||||
}
|
||||
if (
|
||||
el.expiration &&
|
||||
(el.expiration.days > 0 || el.expiration.noncurrent_expiration_days)
|
||||
(el.expiration.days > 0 ||
|
||||
el.expiration.noncurrent_expiration_days ||
|
||||
(el.expiration.newer_noncurrent_expiration_versions &&
|
||||
el.expiration.newer_noncurrent_expiration_versions > 0))
|
||||
) {
|
||||
return <span>Expiry</span>;
|
||||
}
|
||||
@@ -170,7 +172,10 @@ const BucketLifecyclePanel = () => {
|
||||
if (el.expiration) {
|
||||
if (el.expiration.days > 0) {
|
||||
return <span>Current</span>;
|
||||
} else if (el.expiration.noncurrent_expiration_days) {
|
||||
} else if (
|
||||
el.expiration.noncurrent_expiration_days ||
|
||||
el.expiration.newer_noncurrent_expiration_versions
|
||||
) {
|
||||
return <span>Non-Current</span>;
|
||||
}
|
||||
}
|
||||
@@ -200,13 +205,6 @@ const BucketLifecyclePanel = () => {
|
||||
if (!el) {
|
||||
return <Fragment />;
|
||||
}
|
||||
if (el.expiration) {
|
||||
if (el.expiration.days > 0) {
|
||||
return <span>{el.expiration.days} days</span>;
|
||||
} else if (el.expiration.noncurrent_expiration_days) {
|
||||
return <span>{el.expiration.noncurrent_expiration_days} days</span>;
|
||||
}
|
||||
}
|
||||
if (el.transition) {
|
||||
if (el.transition.days > 0) {
|
||||
return <span>{el.transition.days} days</span>;
|
||||
@@ -214,6 +212,19 @@ const BucketLifecyclePanel = () => {
|
||||
return <span>{el.transition.noncurrent_transition_days} days</span>;
|
||||
}
|
||||
}
|
||||
if (el.expiration) {
|
||||
if (el.expiration.days > 0) {
|
||||
return <span>{el.expiration.days} days</span>;
|
||||
} else if (el.expiration.noncurrent_expiration_days) {
|
||||
return <span>{el.expiration.noncurrent_expiration_days} days</span>;
|
||||
} else {
|
||||
return (
|
||||
<span>
|
||||
{el.expiration.newer_noncurrent_expiration_versions} versions
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -42,6 +42,7 @@ interface IExpirationLifecycle {
|
||||
date: string;
|
||||
delete_marker?: boolean;
|
||||
noncurrent_expiration_days?: number;
|
||||
newer_noncurrent_expiration_versions?: number;
|
||||
}
|
||||
|
||||
interface ITransitionLifecycle {
|
||||
|
||||
@@ -5385,6 +5385,12 @@ func init() {
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"newer_noncurrentversion_expiration_versions": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_expiration_days": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
@@ -6190,6 +6196,10 @@ func init() {
|
||||
"delete_marker": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"newer_noncurrent_expiration_versions": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"noncurrent_expiration_days": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
@@ -14656,6 +14666,12 @@ func init() {
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"newer_noncurrentversion_expiration_versions": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"default": 0
|
||||
},
|
||||
"noncurrentversion_expiration_days": {
|
||||
"description": "Non required, can be set in case of expiration is enabled",
|
||||
"type": "integer",
|
||||
@@ -15456,6 +15472,10 @@ func init() {
|
||||
"delete_marker": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"newer_noncurrent_expiration_versions": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"noncurrent_expiration_days": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
|
||||
@@ -90,7 +90,6 @@ func getBucketLifecycle(ctx context.Context, client MinioClient, bucketName stri
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var rules []*models.ObjectBucketLifecycle
|
||||
|
||||
for _, rule := range lifecycleList.Rules {
|
||||
@@ -115,10 +114,11 @@ func getBucketLifecycle(ctx context.Context, client MinioClient, bucketName stri
|
||||
Status: rule.Status,
|
||||
Prefix: rulePrefix,
|
||||
Expiration: &models.ExpirationResponse{
|
||||
Date: rule.Expiration.Date.Format(time.RFC3339),
|
||||
Days: int64(rule.Expiration.Days),
|
||||
DeleteMarker: rule.Expiration.DeleteMarker.IsEnabled(),
|
||||
NoncurrentExpirationDays: int64(rule.NoncurrentVersionExpiration.NoncurrentDays),
|
||||
Date: rule.Expiration.Date.Format(time.RFC3339),
|
||||
Days: int64(rule.Expiration.Days),
|
||||
DeleteMarker: rule.Expiration.DeleteMarker.IsEnabled(),
|
||||
NoncurrentExpirationDays: int64(rule.NoncurrentVersionExpiration.NoncurrentDays),
|
||||
NewerNoncurrentExpirationVersions: int64(rule.NoncurrentVersionExpiration.NewerNoncurrentVersions),
|
||||
},
|
||||
Transition: &models.TransitionResponse{
|
||||
Date: rule.Transition.Date.Format(time.RFC3339),
|
||||
@@ -178,7 +178,7 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params bucketAp
|
||||
switch params.Body.Type {
|
||||
case models.AddBucketLifecycleTypeTransition:
|
||||
if params.Body.TransitionDays == 0 && params.Body.NoncurrentversionTransitionDays == 0 {
|
||||
return errors.New("only one expiry configuration can be set (days or date)")
|
||||
return errors.New("you must provide a value for transition days or date")
|
||||
}
|
||||
|
||||
status := !params.Body.Disable
|
||||
@@ -195,12 +195,13 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params bucketAp
|
||||
noncurrentVersionTransitionStorageClass := strings.ToUpper(params.Body.NoncurrentversionTransitionStorageClass)
|
||||
opts.NoncurrentVersionTransitionDays = &noncurrentVersionTransitionDays
|
||||
opts.NoncurrentVersionTransitionStorageClass = &noncurrentVersionTransitionStorageClass
|
||||
} else {
|
||||
} else if params.Body.TransitionDays > 0 {
|
||||
tdays := strconv.Itoa(int(params.Body.TransitionDays))
|
||||
sclass := strings.ToUpper(params.Body.StorageClass)
|
||||
opts.TransitionDays = &tdays
|
||||
opts.StorageClass = &sclass
|
||||
}
|
||||
|
||||
case models.AddBucketLifecycleTypeExpiry:
|
||||
// Verify if expiry items are set
|
||||
if params.Body.NoncurrentversionTransitionDays != 0 {
|
||||
@@ -220,10 +221,15 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params bucketAp
|
||||
ExpiredObjectDeleteMarker: ¶ms.Body.ExpiredObjectDeleteMarker,
|
||||
}
|
||||
|
||||
if params.Body.NoncurrentversionExpirationDays > 0 {
|
||||
if params.Body.NewerNoncurrentversionExpirationVersions > 0 {
|
||||
versions := int(params.Body.NewerNoncurrentversionExpirationVersions)
|
||||
opts.NewerNoncurrentExpirationVersions = &versions
|
||||
}
|
||||
switch {
|
||||
case params.Body.NoncurrentversionExpirationDays > 0:
|
||||
days := int(params.Body.NoncurrentversionExpirationDays)
|
||||
opts.NoncurrentVersionExpirationDays = &days
|
||||
} else {
|
||||
case params.Body.ExpiryDays > 0:
|
||||
days := strconv.Itoa(int(params.Body.ExpiryDays))
|
||||
opts.ExpiryDays = &days
|
||||
}
|
||||
|
||||
@@ -5067,6 +5067,9 @@ definitions:
|
||||
noncurrent_expiration_days:
|
||||
type: integer
|
||||
format: int64
|
||||
newer_noncurrent_expiration_versions:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
transitionResponse:
|
||||
type: object
|
||||
@@ -5154,6 +5157,11 @@ definitions:
|
||||
type: integer
|
||||
format: int32
|
||||
default: 0
|
||||
newer_noncurrentversion_expiration_versions:
|
||||
description: Non required, can be set in case of expiration 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
|
||||
|
||||
Reference in New Issue
Block a user