Skip to content

Commit

Permalink
Add UI to select number of non-current versions subject to ILM expiry…
Browse files Browse the repository at this point in the history
… rule (minio#3088)
  • Loading branch information
jinapurapu authored and cesnietor committed Jan 12, 2024
1 parent 3d4e97d commit 86d51a6
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 28 deletions.
3 changes: 3 additions & 0 deletions models/add_bucket_lifecycle.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions models/expiration_response.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions portal-ui/src/api/consoleApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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]);

Expand All @@ -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 = {
Expand All @@ -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;
Expand Down Expand Up @@ -184,7 +197,6 @@ const AddLifecycleModal = ({
dispatch(setModalErrorSnackMessage(errorToHandler(err)));
});
};

return (
<ModalWrapper
modalOpen={open}
Expand Down Expand Up @@ -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>) => {
Expand All @@ -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>
}
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ const BucketLifecyclePanel = () => {
.getBucketLifecycle(bucketName)
.then((res) => {
const records = get(res.data, "lifecycle", []);

setLifecycleRecords(records || []);
setLoadingLifecycle(false);
})
Expand Down Expand Up @@ -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>;
}
Expand All @@ -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>;
}
}
Expand Down Expand Up @@ -200,20 +205,26 @@ 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>;
} else if (el.transition.noncurrent_transition_days) {
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>
);
}
}
},
},
{
Expand Down
1 change: 1 addition & 0 deletions portal-ui/src/screens/Console/Buckets/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ interface IExpirationLifecycle {
date: string;
delete_marker?: boolean;
noncurrent_expiration_days?: number;
newer_noncurrent_expiration_versions?: number;
}

interface ITransitionLifecycle {
Expand Down
20 changes: 20 additions & 0 deletions restapi/embedded_spec.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 15 additions & 9 deletions restapi/user_buckets_lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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),
Expand Down Expand Up @@ -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
Expand All @@ -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 {
Expand All @@ -220,10 +221,15 @@ func addBucketLifecycle(ctx context.Context, client MinioClient, params bucketAp
ExpiredObjectDeleteMarker: &params.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
}
Expand Down
8 changes: 8 additions & 0 deletions swagger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5067,6 +5067,9 @@ definitions:
noncurrent_expiration_days:
type: integer
format: int64
newer_noncurrent_expiration_versions:
type: integer
format: int64

transitionResponse:
type: object
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 86d51a6

Please sign in to comment.