Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
vtalas committed Jan 10, 2025
1 parent c1be1bd commit 7891c18
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 70 deletions.
70 changes: 3 additions & 67 deletions src/appmixer/cloudflare/jobs.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const ZoneCloudflareClient = require('./lists/CloudflareListClient');
const wafJobs = require('./waf/jobs.waf');
const wafJobs = require('./jobs.waf');
const listsJobs = require('./jobs.lists');

module.exports = async (context) => {

Expand All @@ -15,7 +15,7 @@ module.exports = async (context) => {
await context.log('trace', '[CloudFlare] rule delete job started.');

try {
await deleteExpireIpsFromList(context);
await listsJobs.deleteExpireIpsFromList(context);
await wafJobs.deleteExpireIps(context);
} finally {
lock.unlock();
Expand All @@ -32,70 +32,6 @@ module.exports = async (context) => {
}
});

const deleteExpireIpsFromList = async function(context) {

const expired = await getExpiredItems(context);

const groups = Object.values(expired);

const promises = groups.map(chunk => {

const { email, apiKey, account, list } = chunk.auth;

context.log('info', { stage: '[CloudFlare] removing ', ips: chunk.ips, list, account });

const client = new ZoneCloudflareClient({ email, apiKey });
// https://developers.cloudflare.com/api/operations/lists-delete-list-items
return client.callEndpoint(context, {
method: 'DELETE',
action: `/accounts/${account}/rules/lists/${list}/items`,
data: { items: chunk.ips }
});
});

const itemsToDelete = { ids: [], lists: [] };

(await Promise.allSettled(promises)).forEach(async (result, i) => {
if (result.status === 'fulfilled') {
itemsToDelete.ids = itemsToDelete.ids.concat(groups[i].ips);
itemsToDelete.lists.push(groups[i]?.auth?.list);
} else {
const operations = groups[i].ips.map(item => ({
updateOne: {
filter: { id: item.id }, update: { $set: { mtime: new Date } }
}
}));
await (context.db.collection(IPListModel.collection)).bulkWrite(operations);
}
});

if (itemsToDelete.ids.length) {
const deleted = await context.db.collection(IPListModel.collection)
.deleteMany({ id: { $in: itemsToDelete.ids.map(item => item.id) } });
await context.log('info', {
stage: `[CloudFlare] Deleted total ${deleted.deletedCount} ips.`,
lists: itemsToDelete.lists,
itemIds: itemsToDelete.ids
});
}
};

const getExpiredItems = async function(context) {

const expired = await context.db.collection(IPListModel.collection)
.find({ removeAfter: { $lt: Date.now() } })
.toArray();

return expired.reduce((res, item) => {
const key = item.auth.list; // listId
res[key] = res[key] || { ips: [] };
res[key].auth = item.auth;
res[key].ips.push({ id: item.id });

return res;
}, {});
};

// Self-healing job to remove rules that have created>mtime. These rules are stuck in the system and should be removed.
await context.scheduleJob('cloud-flare-lists-ips-cleanup-job', config.cleanup.schedule, async () => {

Expand Down
67 changes: 67 additions & 0 deletions src/appmixer/cloudflare/jobs.lists.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const CloudflareListClient = require('./lists/CloudflareListClient');

const deleteExpireIpsFromList = async function(context) {

const expired = await getExpiredItems(context);

const groups = Object.values(expired);

const promises = groups.map(chunk => {

const { email, apiKey, account, list } = chunk.auth;

context.log('info', { stage: '[CloudFlare] removing ', ips: chunk.ips, list, account });

const client = new CloudflareListClient({ email, apiKey });
// https://developers.cloudflare.com/api/operations/lists-delete-list-items
return client.callEndpoint(context, {
method: 'DELETE', action: `/accounts/${account}/rules/lists/${list}/items`, data: { items: chunk.ips }
});
});

const itemsToDelete = { ids: [], lists: [] };

(await Promise.allSettled(promises)).forEach(async (result, i) => {
if (result.status === 'fulfilled') {
itemsToDelete.ids = itemsToDelete.ids.concat(groups[i].ips);
itemsToDelete.lists.push(groups[i]?.auth?.list);
} else {
const operations = groups[i].ips.map(item => ({
updateOne: {
filter: { id: item.id }, update: { $set: { mtime: new Date } }
}
}));
await (context.db.collection(IPListModel.collection)).bulkWrite(operations);
}
});

if (itemsToDelete.ids.length) {
const deleted = await context.db.collection(IPListModel.collection)
.deleteMany({ id: { $in: itemsToDelete.ids.map(item => item.id) } });
await context.log('info', {
stage: `[CloudFlare] Deleted total ${deleted.deletedCount} ips.`,
lists: itemsToDelete.lists,
itemIds: itemsToDelete.ids
});
}
};

const getExpiredItems = async function(context) {

const expired = await context.db.collection(IPListModel.collection)
.find({ removeAfter: { $lt: Date.now() } })
.toArray();

return expired.reduce((res, item) => {
const key = item.auth.list; // listId
res[key] = res[key] || { ips: [] };
res[key].auth = item.auth;
res[key].ips.push({ id: item.id });

return res;
}, {});
};

module.exports = {
deleteExpireIpsFromList
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const CloudflareWAFClient = require('./CloudflareWAFClient');
const lib = require('./lib');
const CloudflareWAFClient = require('./waf/CloudflareWAFClient');
const lib = require('./waf/lib');

const deleteExpireIps = async function(context) {

Expand Down
2 changes: 1 addition & 1 deletion src/appmixer/cloudflare/lists/CloudflareListClient.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = class ZoneCloudflareClient {
module.exports = class CloudflareListClient {

constructor({ email, apiKey, zoneId, token }) {
this.email = email;
Expand Down

0 comments on commit 7891c18

Please sign in to comment.