Skip to content

Commit 5b2f75c

Browse files
authored
Merge pull request #9174 from romayalon/romy-nc-health-bucket-account-check
NC | Health | Add buckets/accounts count and limit check
2 parents f559d9b + bb70839 commit 5b2f75c

File tree

4 files changed

+162
-5
lines changed

4 files changed

+162
-5
lines changed

config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,9 @@ config.NC_DISABLE_SCHEMA_CHECK = false;
10411041
config.ENTROPY_DISK_SIZE_THRESHOLD = 100 * 1024 * 1024;
10421042
config.ENTROPY_MIN_THRESHOLD = 512;
10431043

1044+
config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING = 5000;
1045+
config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING = 5000;
1046+
10441047
////////// NC LIFECYLE //////////
10451048

10461049
config.NC_LIFECYCLE_LOGS_DIR = '/var/log/noobaa/lifecycle';

docs/NooBaaNonContainerized/Health.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ For more details about NooBaa RPM installation, see - [Getting Started](./Gettin
2626
- `NooBaa endpoints health`
2727
- Ensuring that the NooBaa endpoint is running.
2828
- `NooBaa accounts Health`
29-
- Iterating accounts under the config directory.
29+
- Counting and Iterating accounts under the config directory.
3030
- Confirming the existence of the account's configuration file and its validity as a JSON file.
3131
- Verifying that the account's `new_buckets_path` is defined and `allow_bucket_creation` is set to true.
3232
- Ensuring that the account has read and write access to its new_buckets_path.
33+
- Verifying that the number of accounts didn't exceed the supported/tested limit.
3334
- `NooBaa buckets health`
34-
- Iterating buckets under the config directory.
35+
- Counting and Iterating buckets under the config directory.
3536
- Confirming the existence of the bucket's configuration file and its validity as a JSON file.
3637
- Verifying that the underlying storage path of a bucket exists.
38+
- Verifying that the number of buckets didn't exceed the supported/tested limit.
3739
- `Config directory health`
3840
- checks if config system and directory data exists
3941
- returns the config directory status
@@ -128,6 +130,10 @@ The output of the Health CLI is a JSON object containing the following propertie
128130
- Enum: See - [Health Errors](#health-errors)
129131
- Description: Error message describing a health issue uncovered by the Health CLI. Will be displayed in Health response if status is NOTOK.
130132

133+
- `warnings`
134+
- Type: Array [{warning_code: String, warning_message: String}]
135+
- Description: Warnings is an array that consists warnings that raised during the health script.
136+
131137
- `service_status`
132138
- Type: String
133139
- Enum: "active" | "inactive" | "missing service status info"
@@ -221,6 +227,7 @@ Output:
221227
"error_code": "NOOBAA_SERVICE_FAILED",
222228
"error_message": "NooBaa service is not started properly, Please verify the service with status command."
223229
},
230+
"warnings": [],
224231
"checks": {
225232
"services": [
226233
{
@@ -244,6 +251,7 @@ Output:
244251
"error_type": "TEMPORARY"
245252
},
246253
"accounts_status": {
254+
"count": 3,
247255
"invalid_accounts": [
248256
{
249257
"name": "account_invalid",
@@ -263,6 +271,7 @@ Output:
263271
"error_type": "PERSISTENT"
264272
},
265273
"buckets_status": {
274+
"count": 3,
266275
"invalid_buckets": [
267276
{
268277
"name": "bucket1.json",
@@ -283,7 +292,8 @@ Output:
283292
],
284293
"error_type": "PERSISTENT"
285294
},
286-
"connectoins_status": {
295+
"connectins_status": {
296+
"count": 2,
287297
"invalid_connections": [
288298
{
289299
"name": "notif_invalid",
@@ -464,3 +474,23 @@ The following error codes will be associated with a specific Bucket or Account s
464474
- Start NooBaa service
465475
- Run `noobaa-cli upgrade`
466476
- Check the in_progress_upgrade the exact reason for the failure.
477+
478+
## Health Warnings
479+
480+
If the Health CLI encounters some issues, the following warnings will be pushed to a warnings array in the health output.
481+
482+
#### 1. Buckets count limit warning
483+
- Warning code: `BUCKETS_COUNT_LIMIT_WARNING`
484+
- Warning message: Number of buckets exceeds the limit of ${config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING}
485+
- Reasons:
486+
- The number of buckets exceeds the supported or tested limit, which may lead to unexpected behavior.
487+
- Resolutions:
488+
- Delete buckets until the total count is below the supported or tested limit.
489+
490+
#### 1. Accounts count limit warning
491+
- Warning code: `ACCOUNTS_COUNT_LIMIT_WARNING`
492+
- Warning message: Number of accounts exceeds the limit of ${config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING}
493+
- Reasons:
494+
- The number of accounts exceeds the supported or tested limit, which may lead to unexpected behavior.
495+
- Resolutions:
496+
- Delete accounts until the total count is below the supported or tested limit.

src/manage_nsfs/health.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ const health_errors = {
7373
}
7474
};
7575

76+
const health_warnings = {
77+
BUCKETS_COUNT_LIMIT_WARNING: {
78+
warning_code: 'BUCKETS_COUNT_LIMIT_WARNING',
79+
warning_message: `Number of buckets exceeds the supported limit of ${config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING}.`,
80+
},
81+
ACCOUNTS_COUNT_LIMIT_WARNING: {
82+
warning_code: 'ACCOUNTS_COUNT_LIMIT_WARNING',
83+
warning_message: `Number of accounts exceeds the supported limit of ${config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING}.`,
84+
}
85+
};
86+
7687
const fork_response_code = {
7788
RUNNING: {
7889
response_code: 'RUNNING',
@@ -146,12 +157,13 @@ class NSFSHealth {
146157
if (this.all_connection_details) connection_details = await this.get_connection_status();
147158
if (this.notif_storage_threshold) notif_storage_threshold_details = this.get_notif_storage_threshold_status();
148159
if (this.lifecycle) latest_lifecycle_run_status = await this.get_lifecycle_health_status();
149-
160+
const warnings = this.get_warnings_array({ buckets_count: bucket_details?.count, accounts_count: account_details?.count });
150161
const health = {
151162
service_name: NOOBAA_SERVICE_NAME,
152163
status: service_health,
153164
memory: memory,
154165
error: error_code,
166+
warnings,
155167
checks: {
156168
services: [noobaa_service_state],
157169
endpoint: {
@@ -160,11 +172,13 @@ class NSFSHealth {
160172
},
161173
config_directory_status,
162174
accounts_status: {
175+
count: account_details?.count || undefined,
163176
invalid_accounts: account_details === undefined ? undefined : account_details.invalid_storages,
164177
valid_accounts: account_details === undefined ? undefined : account_details.valid_storages,
165178
error_type: health_errors_tyes.PERSISTENT,
166179
},
167180
buckets_status: {
181+
count: bucket_details?.count || undefined,
168182
invalid_buckets: bucket_details === undefined ? undefined : bucket_details.invalid_storages,
169183
valid_buckets: bucket_details === undefined ? undefined : bucket_details.valid_storages,
170184
error_type: health_errors_tyes.PERSISTENT,
@@ -220,6 +234,25 @@ class NSFSHealth {
220234
}
221235
}
222236

237+
/**
238+
* get_warnings_array returns an array of warnings based on the health check parameters
239+
* @param {{
240+
* buckets_count?: Number,
241+
* accounts_count?: Number
242+
* }} params
243+
* @returns {Array[Object]}
244+
*/
245+
get_warnings_array({ buckets_count = 0, accounts_count = 0 }) {
246+
const warnings = [];
247+
if (this.all_bucket_details && buckets_count > config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING) {
248+
warnings.push(health_warnings.BUCKETS_COUNT_LIMIT_WARNING);
249+
}
250+
if (this.all_account_details && accounts_count > config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING) {
251+
warnings.push(health_warnings.ACCOUNTS_COUNT_LIMIT_WARNING);
252+
}
253+
return warnings;
254+
}
255+
223256
async get_service_state(service_name) {
224257
let pid;
225258
const service_status = await get_service_status(service_name);
@@ -430,6 +463,7 @@ class NSFSHealth {
430463
}
431464
}
432465
return {
466+
count: valid_storages.length + invalid_storages.length,
433467
invalid_storages: invalid_storages,
434468
valid_storages: valid_storages
435469
};
@@ -818,4 +852,5 @@ function _should_skip_health_access_check() {
818852
}
819853

820854
exports.get_health_status = get_health_status;
855+
exports.health_warnings = health_warnings;
821856
exports.NSFSHealth = NSFSHealth;

src/test/integration_tests/nc/cli/test_nc_health.js

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Copyright (C) 2016 NooBaa */
2-
/*eslint max-lines-per-function: ['error', 700]*/
2+
/*eslint max-lines-per-function: ['error', 800]*/
33

44
'use strict';
55

@@ -27,6 +27,7 @@ const DEFAULT_FS_CONFIG = get_process_fs_context();
2727

2828
const bucket_storage_path = path.join(tmp_fs_path, 'bucket_storage_path');
2929
const os = require('os');
30+
const { health_warnings } = require('../../../../manage_nsfs/health');
3031
const hostname = os.hostname();
3132

3233
const valid_system_json = {
@@ -134,6 +135,9 @@ mocha.describe('nsfs nc health', function() {
134135
mocha.describe('health check', function() {
135136
this.timeout(10000);// eslint-disable-line no-invalid-this
136137
const new_buckets_path = `${root_path}new_buckets_path_user1/`;
138+
const orig_health_buckets_count_limit = config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING;
139+
const orig_health_accounts_count_limit = config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING;
140+
137141
const account1_options = {
138142
name: 'account1',
139143
uid: process.getuid(),
@@ -195,6 +199,8 @@ mocha.describe('nsfs nc health', function() {
195199
mocha.afterEach(async () => {
196200
await fs_utils.file_delete(config_fs.config_json_path);
197201
restore_health_if_needed(Health);
202+
config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING = orig_health_buckets_count_limit;
203+
config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING = orig_health_accounts_count_limit;
198204
});
199205

200206
mocha.it('Health all condition is success', async function() {
@@ -640,6 +646,89 @@ mocha.describe('nsfs nc health', function() {
640646
await exec_manage_cli(TYPES.ACCOUNT, ACTIONS.DELETE, { config_root, name: account_invalid.name });
641647
});
642648

649+
mocha.it('accounts count below limit', async function() {
650+
Health.all_account_details = true;
651+
Health.all_bucket_details = true;
652+
test_utils.set_health_mock_functions(Health, {
653+
get_service_state: get_service_state_mock_default_response,
654+
get_endpoint_response: get_endpoint_response_mock_default_response,
655+
get_system_config_file: get_system_config_mock_default_response
656+
});
657+
const health_status = await Health.nc_nsfs_health();
658+
console.log('health_status', health_status);
659+
assert.strictEqual(health_status.checks.buckets_status.count, 1);
660+
assert.strictEqual(health_status.checks.accounts_status.count, 1);
661+
assert.strictEqual(health_status.warnings.length, 0);
662+
});
663+
664+
mocha.it('accounts count above limit - should emit warning', async function() {
665+
Health.all_account_details = true;
666+
Health.all_bucket_details = true;
667+
config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING = 0;
668+
test_utils.set_health_mock_functions(Health, {
669+
get_service_state: get_service_state_mock_default_response,
670+
get_endpoint_response: get_endpoint_response_mock_default_response,
671+
get_system_config_file: get_system_config_mock_default_response
672+
});
673+
const health_status = await Health.nc_nsfs_health();
674+
console.log('health_status', health_status);
675+
assert.strictEqual(health_status.checks.buckets_status.count, 1);
676+
assert.strictEqual(health_status.checks.accounts_status.count, 1);
677+
assert.strictEqual(health_status.warnings.length, 1);
678+
assert.strictEqual(health_status.warnings.includes(health_warnings.ACCOUNTS_COUNT_LIMIT_WARNING), true);
679+
});
680+
681+
mocha.it('buckets count below limit', async function() {
682+
Health.all_account_details = true;
683+
Health.all_bucket_details = true;
684+
test_utils.set_health_mock_functions(Health, {
685+
get_service_state: get_service_state_mock_default_response,
686+
get_endpoint_response: get_endpoint_response_mock_default_response,
687+
get_system_config_file: get_system_config_mock_default_response
688+
});
689+
const health_status = await Health.nc_nsfs_health();
690+
console.log('health_status', health_status);
691+
assert.strictEqual(health_status.checks.buckets_status.count, 1);
692+
assert.strictEqual(health_status.checks.accounts_status.count, 1);
693+
assert.strictEqual(health_status.warnings.length, 0);
694+
});
695+
696+
mocha.it('buckets count above limit - should emit warning', async function() {
697+
config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING = 0;
698+
Health.all_account_details = true;
699+
Health.all_bucket_details = true;
700+
test_utils.set_health_mock_functions(Health, {
701+
get_service_state: get_service_state_mock_default_response,
702+
get_endpoint_response: get_endpoint_response_mock_default_response,
703+
get_system_config_file: get_system_config_mock_default_response
704+
});
705+
const health_status = await Health.nc_nsfs_health();
706+
console.log('health_status', health_status);
707+
assert.strictEqual(health_status.checks.buckets_status.count, 1);
708+
assert.strictEqual(health_status.checks.accounts_status.count, 1);
709+
assert.strictEqual(health_status.warnings.length, 1);
710+
assert.strictEqual(health_status.warnings.includes(health_warnings.BUCKETS_COUNT_LIMIT_WARNING), true);
711+
});
712+
713+
mocha.it('buckets and accounts count above limit - should emit warnings', async function() {
714+
Health.all_account_details = true;
715+
Health.all_bucket_details = true;
716+
config.NC_HEALTH_BUCKETS_COUNT_LIMIT_WARNING = 0;
717+
config.NC_HEALTH_ACCOUNTS_COUNT_LIMIT_WARNING = 0;
718+
test_utils.set_health_mock_functions(Health, {
719+
get_service_state: get_service_state_mock_default_response,
720+
get_endpoint_response: get_endpoint_response_mock_default_response,
721+
get_system_config_file: get_system_config_mock_default_response
722+
});
723+
const health_status = await Health.nc_nsfs_health();
724+
console.log('health_status', health_status);
725+
assert.strictEqual(health_status.checks.buckets_status.count, 1);
726+
assert.strictEqual(health_status.checks.accounts_status.count, 1);
727+
assert.strictEqual(health_status.warnings.length, 2);
728+
assert.strictEqual(health_status.warnings.includes(health_warnings.ACCOUNTS_COUNT_LIMIT_WARNING), true);
729+
assert.strictEqual(health_status.warnings.includes(health_warnings.BUCKETS_COUNT_LIMIT_WARNING), true);
730+
});
731+
643732
mocha.it('Health all condition - failed config directory upgrade status', async function() {
644733
valid_system_json.config_directory = {
645734
config_dir_version: config_fs.config_dir_version,

0 commit comments

Comments
 (0)