Skip to content

Commit 04d2ead

Browse files
authored
Merge pull request #8913 from nadavMiz/nc-lifecycle-notifications-fix
NC | lifecycle | fix notifications
2 parents af65596 + 10e1156 commit 04d2ead

File tree

2 files changed

+286
-131
lines changed

2 files changed

+286
-131
lines changed

src/manage_nsfs/nc_lifecycle.js

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const ManageCLIError = require('./manage_nsfs_cli_errors').ManageCLIError;
1717
const { throw_cli_error, get_service_status, NOOBAA_SERVICE_NAME,
1818
is_desired_time, record_current_time } = require('./manage_nsfs_cli_utils');
1919
const SensitiveString = require('../util/sensitive_string');
20+
const {CONFIG_TYPES} = require('../sdk/config_fs');
2021

2122
// TODO:
2223
// implement
@@ -161,7 +162,11 @@ async function process_buckets(config_fs, bucket_names, system_json) {
161162
*/
162163
async function process_bucket(config_fs, bucket_name, system_json) {
163164
const bucket_json = await config_fs.get_bucket_by_name(bucket_name, config_fs_options);
164-
const account = { email: '', nsfs_account_config: config_fs.fs_context, access_keys: [] };
165+
const account = await config_fs.get_identity_by_id(bucket_json.owner_account, CONFIG_TYPES.ACCOUNT, {silent_if_missing: true});
166+
if (!account) {
167+
dbg.warn(`process_bucket - bucket owner ${bucket_json.owner_account} does not exist for bucket ${bucket_name}. skipping lifecycle for this bucket`);
168+
return;
169+
}
165170
const object_sdk = new NsfsObjectSDK('', config_fs, account, bucket_json.versioning, config_fs.config_root, system_json);
166171
await object_sdk._simple_load_requesting_account();
167172
const should_notify = notifications_util.should_notify_on_event(bucket_json, notifications_util.OP_TO_EVENT.lifecycle_delete.name);
@@ -210,40 +215,6 @@ async function process_rules(config_fs, bucket_json, object_sdk, should_notify)
210215
}
211216
}
212217

213-
async function send_lifecycle_notifications(delete_res, bucket_json, object_sdk) {
214-
const writes = [];
215-
for (const deleted_obj of delete_res) {
216-
if (delete_res.err_code) continue;
217-
for (const notif of bucket_json.notifications) {
218-
if (notifications_util.check_notif_relevant(notif, {
219-
op_name: 'lifecycle_delete',
220-
s3_event_method: deleted_obj.delete_marker_created ? 'DeleteMarkerCreated' : 'Delete',
221-
})) {
222-
//remember that this deletion needs a notif for this specific notification conf
223-
writes.push({notif, deleted_obj});
224-
}
225-
}
226-
}
227-
228-
//required format by compose_notification_lifecycle
229-
bucket_json.bucket_owner = new SensitiveString(bucket_json.bucket_owner);
230-
231-
//if any notifications are needed, write them in notification log file
232-
//(otherwise don't do any unnecessary filesystem actions)
233-
if (writes.length > 0) {
234-
let logger;
235-
try {
236-
logger = notifications_util.get_notification_logger('SHARED');
237-
await P.map_with_concurrency(100, writes, async write => {
238-
const notif = notifications_util.compose_notification_lifecycle(write.deleted_obj, write.notif, bucket_json, object_sdk);
239-
logger.append(JSON.stringify(notif));
240-
});
241-
} finally {
242-
if (logger) logger.close();
243-
}
244-
}
245-
}
246-
247218
/**
248219
* process_rule processes the lifecycle rule for a bucket
249220
* TODO - implement notifications for the deleted objects (check if needed for abort mpus as well)
@@ -281,7 +252,7 @@ async function process_rule(config_fs, lifecycle_rule, index, bucket_json, objec
281252
})
282253
});
283254
if (should_notify) {
284-
await send_lifecycle_notifications(delete_res, bucket_json, object_sdk);
255+
await send_lifecycle_notifications(delete_res, candidates.delete_candidates, bucket_json, object_sdk);
285256
}
286257
}
287258

@@ -323,6 +294,70 @@ async function abort_mpus(candidates, object_sdk) {
323294
return abort_mpus_reply;
324295
}
325296

297+
/////////////////////////////////
298+
////// NOTIFICATION HELPERS /////
299+
/////////////////////////////////
300+
301+
/**
302+
*
303+
* @param {Object} delete_res
304+
* @param {Object} delete_obj_info
305+
* @returns
306+
*/
307+
function create_notification_delete_object(delete_res, delete_obj_info) {
308+
return {
309+
...delete_obj_info,
310+
created_delete_marker: delete_res.created_delete_marker,
311+
version_id: delete_res.created_delete_marker ? delete_res.created_version_id : delete_obj_info.version_id,
312+
};
313+
}
314+
315+
/**
316+
*
317+
* @param {Object[]} delete_res array of delete results
318+
* @param {Object[]} delete_candidates array of delete candidates object info
319+
* @param {Object} bucket_json
320+
* @param {Object} object_sdk
321+
* @returns {Promise<Void>}
322+
* NOTE implementation assumes delete_candidates and delete_res uses the same index. this assumption is also made in
323+
* s3_post_bucket_delete.js.
324+
*/
325+
async function send_lifecycle_notifications(delete_res, delete_candidates, bucket_json, object_sdk) {
326+
const writes = [];
327+
for (let i = 0; i < delete_res.length; ++i) {
328+
if (delete_res[i].err_code) continue;
329+
for (const notif of bucket_json.notifications) {
330+
if (notifications_util.check_notif_relevant(notif, {
331+
op_name: 'lifecycle_delete',
332+
s3_event_method: delete_res[i].created_delete_marker ? 'DeleteMarkerCreated' : 'Delete',
333+
})) {
334+
const deleted_obj = create_notification_delete_object(delete_res[i], delete_candidates[i]);
335+
//remember that this deletion needs a notif for this specific notification conf
336+
writes.push({notif, deleted_obj});
337+
}
338+
}
339+
}
340+
341+
//required format by compose_notification_lifecycle
342+
bucket_json.bucket_owner = new SensitiveString(object_sdk.requesting_account.name);
343+
344+
//if any notifications are needed, write them in notification log file
345+
//(otherwise don't do any unnecessary filesystem actions)
346+
if (writes.length > 0) {
347+
let logger;
348+
try {
349+
logger = notifications_util.get_notification_logger('SHARED');
350+
await P.map_with_concurrency(100, writes, async write => {
351+
const notif = notifications_util.compose_notification_lifecycle(write.deleted_obj, write.notif, bucket_json, object_sdk);
352+
await logger.append(JSON.stringify(notif));
353+
});
354+
} finally {
355+
if (logger) await logger.close();
356+
}
357+
}
358+
}
359+
360+
326361
/////////////////////////////////
327362
//////// GENERAL HELPERS ////////
328363
/////////////////////////////////
@@ -472,9 +507,11 @@ async function get_candidates_by_expiration_rule_posix(lifecycle_rule, bucket_js
472507
limit: config.NC_LIFECYCLE_LIST_BATCH_SIZE
473508
});
474509
objects_list.objects.forEach(obj => {
475-
const object_info = _get_lifecycle_object_info_from_list_object_entry(obj);
476-
if (filter_func(object_info)) {
477-
filtered_objects.push({key: object_info.key});
510+
const lifecycle_object = _get_lifecycle_object_info_from_list_object_entry(obj);
511+
if (filter_func(lifecycle_object)) {
512+
//need to delete latest. so remove version_id if exists
513+
const candidate = _.omit(obj, ['version_id']);
514+
filtered_objects.push(candidate);
478515
}
479516
});
480517

0 commit comments

Comments
 (0)